package com.yycx.module.bus.provider.service.impl;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.yycx.common.base.entity.EntityMap;
import com.yycx.common.base.utils.FlymeUtils;
import com.yycx.common.constants.CommonConstants;
import com.yycx.common.mybatis.base.service.impl.BaseServiceImpl;
import com.yycx.common.mybatis.model.ResultBody;
import com.yycx.common.mybatis.query.CriteriaDelete;
import com.yycx.common.mybatis.query.CriteriaQuery;
import com.yycx.common.mybatis.query.CriteriaSave;
import com.yycx.common.mybatis.query.CriteriaUpdate;
import com.yycx.common.security.OpenHelper;
import com.yycx.common.utils.ApiAssert;
import com.yycx.common.utils.DateUtils;
import com.yycx.common.utils.ReflectionUtils;
import com.yycx.groovy.provider.script.MyGroovyScriptEngine;
import com.yycx.module.bus.client.entity.*;
import com.yycx.module.bus.client.enums.AmountTypeEnum;
import com.yycx.module.bus.client.enums.DeliveryTypeEnum;
import com.yycx.module.bus.client.enums.SaleTypeEnum;
import com.yycx.module.bus.client.vo.OrderCustomReturn;
import com.yycx.module.bus.client.vo.OrderDetailsVo;
import com.yycx.module.bus.provider.mapper.BusOrderDetailsMapper;
import com.yycx.module.bus.provider.service.*;
import com.yycx.module.file.provider.service.SysFileService;
import com.yycx.module.system.client.entity.SysBank;
import com.yycx.module.system.client.entity.SysFormula;
import com.yycx.module.system.provider.service.SysBankService;
import com.yycx.module.system.provider.service.SysFormulaService;
import lombok.AllArgsConstructor;
import org.flowable.engine.TaskService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 订单明细接口实现类
 *
 * @author flyme
 * @date 2020-08-19
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class BusOrderDetailsServiceImpl extends BaseServiceImpl<BusOrderDetailsMapper, BusOrderDetails> implements BusOrderDetailsService {
    @Autowired
    private BusDrugsService drugsService;

    @Autowired
    private BusOrderService orderService;
    @Autowired
    private BusDrugslotService drugslotService;
    @Autowired
    private BusSupplierRateService supplierRateService;
    @Autowired
    private BusCustomRateService customRateService;
    @Autowired
    private MyGroovyScriptEngine groovyScriptEngine;
    @Autowired
    private SysFormulaService sysFormulaService;

    @Autowired
    private SysFileService fileService;

    @Autowired
    private BusPaymentService paymentService;
    @Autowired
    private BusDeptService deptService;

    @Autowired
    private BusCustomService customService;

    @Autowired
    private BusOrderDetailsService orderDetailsService;

    @Autowired
    private BusInvoiceunitService invoiceunitService;

    @Autowired
    private SysBankService bankService;

    @Autowired
    private TaskService taskService;
    @Autowired
    private BusFinanceService financeService;


    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public ResultBody<EntityMap> beforePageList(CriteriaQuery<BusOrderDetails> cq, BusOrderDetails bod, EntityMap requestMap) {
        Long orderId = bod.getOrderId();
        cq.select(BusOrderDetails.class, "*");
        cq.addSelect(BusOrder.class, "supplierBondType", "customBondType", "takeDate", "orderNo", "invoiceSendType", "delivery");
        cq.addSelect(BusSupplier.class, "supplierName");
        cq.addSelect(BusCustom.class, "customName", "areaName");
        cq.addSelect(BusDrugs.class, "drugsName", "drugsSpec");
        cq.addSelect(BusDrugslot.class, "drugsLotNo");
        if (FlymeUtils.isNotEmpty(orderId)) {
            cq.and(e -> e.eq(true, "ord.orderId", orderId).or().eq(true, "ord.parentId", orderId));
        }
        cq.eq(BusOrderDetails.class, "orderDetailsState", CommonConstants.ENABLED);
        cq.createJoin(BusSupplier.class);
        cq.createJoin(BusDrugs.class);
        cq.createJoin(BusCustom.class);
        cq.createJoin(BusOrder.class);
        cq.createJoin(BusDrugslot.class);
        return ResultBody.ok();
    }

    @Override
    public ResultBody beforeListEntityMap(CriteriaQuery<BusOrderDetails> cq, BusOrderDetails busOrderDetails, EntityMap requestMap) {
        cq.select(BusOrderDetails.class, "*");
        cq.addSelect(BusOrder.class, "supplierBondType", "customBondType", "orderNo", "sendDate");
        cq.addSelect(BusSupplier.class, "supplierName");
        cq.addSelect(BusCustom.class, "customName");
        cq.addSelect(BusDrugs.class, "drugsName", "drugsSpec");
        cq.addSelect(BusDrugslot.class, "drugsLotNo");
        cq.eq(BusOrderDetails.class, "orderId");
        cq.eq(BusOrderDetails.class, "orderDetailsState", CommonConstants.ENABLED);
        cq.orderByDesc("bod.createTime");
        cq.createJoin(BusSupplier.class);
        cq.createJoin(BusDrugs.class);
        cq.createJoin(BusCustom.class);
        cq.createJoin(BusOrder.class);
        cq.createJoin(BusDrugslot.class);
        return super.beforeListEntityMap(cq, busOrderDetails, requestMap);
    }

    @Override
    public ResultBody<EntityMap> beforeAdd(CriteriaSave cs, BusOrderDetails orderDetails, EntityMap extra) {
        BigDecimal radio = new BigDecimal("1");
        orderDetails.setCustomBond(new BigDecimal("0"));
        orderDetails.setReturnCustomBond(new BigDecimal("0"));
        orderDetails.setSupplierBondState("0");
        orderDetails.setCustomReturnState("0");
        orderDetails.setSettleAmount2(new BigDecimal("0"));
        orderDetails.setSettleAmount3(new BigDecimal("0"));
        orderDetails.setSettleRealAmount(new BigDecimal("0"));
        orderDetails.setSettleRealAmount2(new BigDecimal("0"));
        orderDetails.setSettleRealAmount3(new BigDecimal("0"));
        orderDetails.setCustomYsk(new BigDecimal("0"));
        orderDetails.setReturnSupplierBond(new BigDecimal("0"));
        orderDetails.setSupplierRealAmount(new BigDecimal("0"));
        orderDetails.setReturnCustomBond(new BigDecimal("0"));
        orderDetails.setCustomOverBond(new BigDecimal("0"));
        orderDetails.setSupplierPayBond(new BigDecimal("0"));
        orderDetails.setSupplierBond(new BigDecimal("0"));
        orderDetails.setLdSupplierRealAmount(new BigDecimal("0"));
        orderDetails.setInvoiceAmount(new BigDecimal("0"));
        orderDetails.setInvoicePaymentAmount(new BigDecimal("0"));
        orderDetails.setSettleState("0");
        orderDetails.setSettleState2("0");
        orderDetails.setSettleState3("0");
        orderDetails.setBudan("0");
        orderDetails.setRadio(radio);
        //计算订单相关金额
        calculateSaleAmount(orderDetails, extra);
        BusOrder busOrder = extra.get("busOrder");
        orderDetails.setOrderDetailsState(CommonConstants.ENABLED);
        Integer supplierBondType = busOrder.getSupplierBondType();
        if (supplierBondType > 0) {
            orderDetails.setSupplierBondState("0");
        } else {
            //设置为不垫付
            orderDetails.setSupplierBondState("-1");
        }
        Integer customBondType = busOrder.getCustomBondType();
        //预付款
        if (customBondType.equals(7)) {
            orderDetails.setCustomYsk(busOrder.getTakeAmount());
        }
        return ResultBody.ok();
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public ResultBody<EntityMap> afterAdd(CriteriaSave cs, BusOrderDetails orderDetails, EntityMap extra) {
        return super.afterAdd(cs, orderDetails, extra);
    }


    @Override
    public ResultBody<EntityMap> beforeEdit(CriteriaUpdate<BusOrderDetails> cu, BusOrderDetails orderDetails, EntityMap extra) {
        Boolean isHesuan = false;
        Integer optType = cu.getInt("optType", CommonConstants.INT_0);
        SaleTypeEnum saleTypeEnum = SaleTypeEnum.Xs;
        if (optType.equals(CommonConstants.INT_1)) {
            //核算操作
            calculateSaleAmountByHesuan(orderDetails);
        }
        if (optType.equals(CommonConstants.INT_0)) {
            //正常计算订单相关金额
            calculateSaleAmount(orderDetails, extra);
            BusOrder busOrder = extra.get("busOrder");
            Integer supplierBondType = busOrder.getSupplierBondType();
            if (supplierBondType > 0) {
                orderDetails.setSupplierBondState("0");
            } else {
                //设置为不垫付
                orderDetails.setSupplierBondState("-1");
            }
            orderDetails.setOrderDetailsState(CommonConstants.ENABLED);
        }
        if (FlymeUtils.isNotEmpty(orderDetails.getReturnAmount()) && FlymeUtils.gtzero(orderDetails.getReturnAmount())) {
            orderDetails.setCustomReturnState("2");
        }
        //订单修正
        if (optType.equals(4)) {
            String sendNo = cu.getParams("sendNo");
            Long customFpId = cu.getLong("customFpId");
            String invoiceAttachment = cu.getParams("invoiceAttachment");
            String sendAttachment = cu.getParams("sendAttachment");
            orderService.updateSendInfo(orderDetails.getOrderId(), sendNo, invoiceAttachment, sendAttachment, customFpId);
        }
        return super.beforeEdit(cu, orderDetails, extra);
    }

    @Override
    public ResultBody<EntityMap> afterEdit(CriteriaUpdate cu, BusOrderDetails orderDetails, EntityMap extra) {
        BusOrder busOrder = extra.get("busOrder");
        Object optType = cu.getInt("optType", CommonConstants.INT_0);
        return super.afterEdit(cu, orderDetails, extra);
    }


    private void calculateSupplierBond(BusOrderDetails orderDetails, BusOrder busOrder) {
        Long orderDetailsId = orderDetails.getOrderDetailsId();

        //供货商资信方式
        Integer supplierBondType = busOrder.getSupplierBondType();
        ApiAssert.isNotEmpty("供货商资信方式不能为空", supplierBondType);
        if (supplierBondType > 0) {
            //垫付款
            BigDecimal supplierBond = new BigDecimal("0");
            //底价(即成本价)
            BigDecimal costAmount = orderDetails.getCostAmount();
            //税金
            BigDecimal supplierGapUpTaxesAmount = orderDetails.getSupplierGapUpTaxesAmount();
            //垫付底价
            if (supplierBondType.equals(1)) {
                supplierBond = costAmount;
            }
            //底价税金
            if (supplierBondType.equals(2) || supplierBondType.equals(3) || supplierBondType.equals(6)) {
                if (supplierBondType.equals(3)) {
                    supplierBond = supplierGapUpTaxesAmount;
                }
                if (supplierBondType.equals(2)) {
                    supplierBond = costAmount.add(supplierGapUpTaxesAmount);
                }
                if (supplierBondType.equals(6)) {
                    supplierBond = costAmount.divide(new BigDecimal("2")).add(supplierGapUpTaxesAmount);
                }
            }
            //全额垫付
            if (supplierBondType.equals(5)) {
                supplierBond = orderDetails.getSaleAmount();
            }
            //销售金额*费率
            if (supplierBondType.equals(8)) {
                supplierBond = orderDetails.getSupplierTaxRate().multiply(orderDetails.getSaleAmount());
            }
            if (FlymeUtils.isEmpty(orderDetails.getSupplierBondState())) {
                orderDetails.setSupplierBondState("0");
            }
            orderDetails.setSupplierBond(supplierBond);
        } else {
            orderDetails.setSupplierBondState("-1");
            orderDetails.setSupplierBond(new BigDecimal("0"));
        }
    }


    private void calculateSupplierBondByHesuan(BusOrderDetails orderDetails, BusOrder busOrder) {
        Long orderDetailsId = orderDetails.getOrderDetailsId();

        //供货商资信方式
        Integer supplierBondType = busOrder.getSupplierBondType();
        ApiAssert.isNotEmpty("供货商资信方式不能为空", supplierBondType);
        if (supplierBondType > 0) {
            //垫付款
            BigDecimal supplierBond = new BigDecimal("0");
            //底价(即成本价)
            BigDecimal costAmount = orderDetails.getCostAmount();
            //税金
            BigDecimal supplierGapUpTaxesAmount = orderDetails.getSupplierGapUpTaxesAmount();
            //垫付底价
            if (supplierBondType.equals(1)) {
                supplierBond = costAmount;
            }
            //底价税金
            if (supplierBondType.equals(2) || supplierBondType.equals(3) || supplierBondType.equals(6)) {
                if (supplierBondType.equals(3)) {
                    supplierBond = supplierGapUpTaxesAmount;
                }
                if (supplierBondType.equals(2)) {
                    supplierBond = costAmount.add(supplierGapUpTaxesAmount);
                }
                if (supplierBondType.equals(6)) {
                    supplierBond = costAmount.divide(new BigDecimal("2")).add(supplierGapUpTaxesAmount);
                }
            }
            //全额垫付
            if (supplierBondType.equals(5)) {
                supplierBond = orderDetails.getSaleAmount();
            }
            //销售金额*费率
            if (supplierBondType.equals(8)) {
                supplierBond = orderDetails.getSupplierTaxRate().multiply(orderDetails.getSaleAmount());
            }
            orderDetails.setSupplierBond(supplierBond);
            BusPayment payment = paymentService.getByOrderIdAndAmountType(busOrder.getOrderId(), AmountTypeEnum.SupplierBond);
            if (FlymeUtils.isNotEmpty(payment)) {
                Integer paymentState = payment.getPaymentState();
                if (!paymentState.equals(2)) {
                    payment.setAmount(supplierBond);
                    paymentService.saveOrUpdate(payment);
                }
            }

        } else {
            orderDetails.setSupplierBond(new BigDecimal("0"));
            paymentService.removeByOrderId(AmountTypeEnum.SupplierBond, busOrder.getOrderId().toString());
        }
    }


    /**
     * 计算相关金额和价格
     *
     * @param orderDetails
     */
    private void calculateSaleAmount(BusOrderDetails orderDetails, EntityMap extra) {
        Long orderId = orderDetails.getOrderId();
        Long orderDetailsId = orderDetails.getOrderDetailsId();
        BigDecimal saleNum = orderDetails.getSaleNum();
        ApiAssert.gtzero("销售数量必须大于0", orderDetails.getSaleNum());
        BigDecimal salePrice = orderDetails.getSalePrice();
        ApiAssert.gtzero("销售价格必须大于0", salePrice);
        ApiAssert.isNotEmpty("订单ID不能为空", orderId);
        Long drugsId = orderDetails.getDrugsId();
        ApiAssert.isNotEmpty("药品ID不能为空", drugsId);
        BusOrder busOrder = orderService.getById(orderId);
        ApiAssert.isNotEmpty("订单不存在", busOrder);
        BusCustom custom = customService.getById(busOrder.getCustomId());
        ApiAssert.isNotEmpty("客户不存在", custom);
        Integer delivery = busOrder.getDelivery();
        //检查资信额度
        if (DeliveryTypeEnum.ZX.getCode().equals(delivery)) {
            BusDept busDept = deptService.getById(busOrder.getDeptId());
            //资信额度
            BigDecimal reputationAmount = busDept.getReputationAmount();
            ApiAssert.gtzero("资信额度未配置", reputationAmount);
            BigDecimal userReputationAmount = FlymeUtils.getBigDecimal(totalReputationAmount(busDept.getDeptId()), "0");
            //总额度-已用额度-当前添加商品销售额
            BigDecimal saleAmount = orderDetails.getSalePrice().multiply(orderDetails.getSaleNum());
            BigDecimal noUserAmount = reputationAmount.subtract(userReputationAmount).subtract(saleAmount);
            ApiAssert.gezero("资信额度不足", noUserAmount);
        }
        Long drugsLotId = orderDetails.getDrugsLotId();
        if (FlymeUtils.isNotEmpty(drugsLotId)) {
            BusDrugslot drugsLot = drugslotService.getById(drugsLotId);
            orderDetails.setCostPrice(drugsLot.getCostPrice());
            //库存数量
            Integer drugsNum = drugsLot.getDrugsNum();
            //已售数量
            BigDecimal settleNum = FlymeUtils.getBigDecimal(orderDetailsService.countByDrugLotId(drugsLotId), "0");
            //累计销售
            BigDecimal settleTotal = saleNum.add(settleNum);
            //剩余库存
            BigDecimal checkNum = settleTotal.subtract(new BigDecimal(drugsNum));

            if (FlymeUtils.gtzero(checkNum)) {
                ApiAssert.failure("库存不足");
            }
        }

        OrderDetailsVo orderDetailsVo = new OrderDetailsVo();
        //初始化计算元素
        initOrderDetailsVo(orderDetails, busOrder, orderDetailsVo);

        calculateCustomBondByAdd(orderDetails, busOrder);

        //传递给后置方法
        extra.put("busOrder", busOrder);
        extra.put("custom", custom);
    }


    private void initOrderDetailsVo(BusOrderDetails orderDetails, BusOrder busOrder, OrderDetailsVo orderDetailsVo) {
        //查询供货方费率配置
        BusSupplierRate supplierRate = supplierRateService.findOrderSupplierRate(orderDetails, busOrder);
        //查询购货方费率配置
        BusCustomRate customRate = customRateService.findCustomRate(orderDetails, busOrder);
        BigDecimal salePrice = orderDetails.getSalePrice();
        BigDecimal saleNum = orderDetails.getSaleNum();
        Long deptId = busOrder.getDeptId();
        Long customId = busOrder.getCustomId();
        Long drugsId = orderDetails.getDrugsId();
        BusDrugs drugs = drugsService.getById(drugsId);
        Long supplierId = busOrder.getSupplierId();
        orderDetails.setCustomRateId(customRate.getCustomRateId());
        orderDetails.setSupplierRateId(supplierRate.getSupplierRateId());
        orderDetails.setSupplierId(supplierId);
        orderDetails.setDeptId(deptId);
        orderDetails.setCustomId(customId);
        orderDetails.setCompanyId(busOrder.getCompanyId());
        orderDetails.setOrganizationId(busOrder.getOrganizationId());
        orderDetails.setSaleManId(busOrder.getSaleManId());
        orderDetails.setSaleDate(busOrder.getSendDate());
        //正常销售
        orderDetails.setSaleType(SaleTypeEnum.Xs.getCode().toString());
        if (FlymeUtils.isEmpty(orderDetails.getSupplierTaxRate())) {
            //供货方垫付款费率
            orderDetails.setSupplierTaxRate(supplierRate.getSupplierTaxRate());
        }
        if (FlymeUtils.isEmpty(orderDetails.getSupplierSettleRate())) {
            //供货方结算费率
            orderDetails.setSupplierSettleRate(supplierRate.getSupplierSettleRate());
        }
        if (FlymeUtils.isEmpty(orderDetails.getHighTaxRateFormulaId())) {
            //供货方高开税金公式
            orderDetails.setHighTaxRateFormulaId(supplierRate.getHighTaxRateFormulaId());
        }
        if (FlymeUtils.isEmpty(orderDetails.getRefundFormulaId())) {
            //供货方返款公式
            orderDetails.setRefundFormulaId(supplierRate.getRefundFormulaId());
        }


        if (FlymeUtils.isEmpty(orderDetails.getCustomSettleGapUpTaxRate())) {
            //结算高开税金费率
            orderDetails.setCustomSettleGapUpTaxRate(customRate.getCustomSettleGapUpTaxRate());
        }
        if (FlymeUtils.isEmpty(orderDetails.getCustomSettleRate())) {
            //结算费率
            orderDetails.setCustomSettleRate(customRate.getCustomSettleRate());
        }
        if (FlymeUtils.isEmpty(orderDetails.getCustomTaxRate())) {
            //结算保证金费率
            orderDetails.setCustomTaxRate(customRate.getCustomTaxRate());
        }
        if (FlymeUtils.isEmpty(orderDetails.getSettleFormulaId())) {
            //结算公式
            orderDetails.setSettleFormulaId(customRate.getSettleFormulaId());
        }


        orderDetailsVo.setCustomRate(customRate);
        orderDetailsVo.setSupplierRate(supplierRate);
        orderDetailsVo.setBusOrder(busOrder);
        BigDecimal saleAmount = salePrice.multiply(saleNum);
        orderDetails.setSaleAmount(saleAmount);


        //查询部门结算价(无配置取药品的结算价配置)
        BusCustomRate deptCustomRate = customRateService.findByDeptId(supplierId, drugsId, deptId);
        BigDecimal settlePrice = new BigDecimal("0");
        if (FlymeUtils.isNotEmpty(orderDetails.getSettlePrice()) && FlymeUtils.gtzero(orderDetails.getSettlePrice())) {
            //取录入的结算价
            settlePrice = orderDetails.getSettlePrice();
        }
        if (FlymeUtils.isNotEmpty(deptCustomRate)) {
            if (FlymeUtils.isEmpty(settlePrice) || FlymeUtils.lezero(settlePrice)) {
                settlePrice = FlymeUtils.getBigDecimal(deptCustomRate.getSettlePrice(), "0");
            }
            //设置结算价格
            orderDetails.setSettlePrice(settlePrice);
            //计算结算发货金额
            orderDetails.setSettleSendAmount(settlePrice.multiply(saleNum));
        }
        orderDetailsVo.setBusOrderDetails(orderDetails);
        Long drugsLotId = orderDetails.getDrugsLotId();
        //默认取全局成本价
        BigDecimal costPrice = FlymeUtils.getBigDecimal(drugs.getCostPrice(), "0");

        if (FlymeUtils.isNotEmpty(orderDetails.getCostPrice())) {
            //取核算成本价
            costPrice = orderDetails.getCostPrice();
        }
        ApiAssert.gtzero("成本价未配置", costPrice);
        BigDecimal costAmount = costPrice.multiply(saleNum);
        //成本价
        orderDetails.setCostPrice(costPrice);
        //成本金额
        orderDetails.setCostAmount(costAmount);
        //供货方高开价(销售-成本)
        BigDecimal supplierGapUpPrice = salePrice.subtract(costPrice);
        //供货方高开金额(高开价格*数量)
        orderDetails.setSupplierGapUpAmount(supplierGapUpPrice.multiply(saleNum));
        //计算供货方高开税金(垫付款税金)
        BigDecimal supplierGapUpTaxesAmount = calculateSupplierGapUpTaxes(orderDetailsVo);
        orderDetails.setSupplierGapUpTaxesAmount(supplierGapUpTaxesAmount);
        //计算供货方应返金额
        BigDecimal supplierRetable = calculateSupplierRetable(orderDetailsVo);
        orderDetails.setSupplierRetable(supplierRetable);
        //必须设置结算价后再计算购货方保证金
        if (FlymeUtils.gtzero(settlePrice)) {
            //购货方底价计算方式1：按结算价 2:按成本价
            Integer floorPriceType = FlymeUtils.getInteger(drugs.getFloorPriceType(), 1);
            // 销售高开价格(销售-结算)
            BigDecimal customGapUpPrice = salePrice.subtract(settlePrice);
            //销售底价
            BigDecimal customFloorAmount = orderDetails.getSettleSendAmount();
            //底价方式采用成本价
            if (floorPriceType.equals(2)) {
                // 销售高开价格(销售-成本)
                customGapUpPrice = salePrice.subtract(costPrice);
                customFloorAmount = costAmount;
            }
            orderDetails.setCustomFloorAmount(customFloorAmount);
            //购货方高开金额
            BigDecimal customGapUpAmount = customGapUpPrice.multiply(saleNum);
            orderDetails.setCustomGapUpAmount(customGapUpAmount);
            // 销售结算高开税金费率
            BigDecimal customSettleGapUpTaxRate = FlymeUtils.getBigDecimal(orderDetails.getCustomSettleGapUpTaxRate(), "0");
            // 计算销售结算高开税金金额
            BigDecimal customSettleGapUpAmount = salePrice.subtract(settlePrice).multiply(saleNum).multiply(customSettleGapUpTaxRate);
            orderDetails.setCustomSettleGapUpAmount(customSettleGapUpAmount);

            // 计算销售保证金税金金额
            BigDecimal customGapUpTaxesAmount = calculateCustomGapUpRateAmount(orderDetailsVo);
            orderDetails.setCustomGapUpTaxesAmount(customGapUpTaxesAmount);

            //计算结算金额
            BigDecimal settleAmount = calculateSettleAmount(orderDetailsVo);
            orderDetails.setSettleAmount(settleAmount);
            //公司利润
            BigDecimal profitAmount = calculateProfitAmount(orderDetailsVo);
            orderDetails.setProfitAmount(profitAmount);
        }

        //计算供货方垫付款
        calculateSupplierBond(orderDetails, busOrder);

    }


    /**
     * 计算相关金额和价格
     *
     * @param orderDetails
     */
    private void calculateSaleAmountByHesuan(BusOrderDetails orderDetails) {
        Long orderId = orderDetails.getOrderId();
        Long orderDetailsId = orderDetails.getOrderDetailsId();
        BusOrderDetails old = getById(orderDetailsId);
        String saleType = orderDetails.getSaleType().toString();
        ApiAssert.isNotEmpty("订单ID不能为空", orderId);
        Long drugsId = orderDetails.getDrugsId();
        ApiAssert.isNotEmpty("药品ID不能为空", drugsId);
        BusOrder busOrder = orderService.getById(orderId);
        ApiAssert.isNotEmpty("订单不存在", busOrder);
        Long deptId = busOrder.getDeptId();
        Long customId = busOrder.getCustomId();
        BusCustom custom = customService.getById(customId);
        ApiAssert.isNotEmpty("客户不存在", custom);
        //按流向结算
        Boolean settleType = custom.getSettleType();
        orderDetails.setCompanyId(busOrder.getCompanyId());
        orderDetails.setOrganizationId(busOrder.getOrganizationId());
        orderDetails.setDeptId(deptId);
        orderDetails.setSaleManId(busOrder.getSaleManId());
        orderDetails.setSaleDate(busOrder.getSendDate());
        orderDetails.setSupplierId(busOrder.getSupplierId());
        orderDetails.setCustomId(customId);
        Integer delivery = busOrder.getDelivery();
        //供货商资信方式
        Integer supplierBondType = busOrder.getSupplierBondType();

        //检查资信额度
        if (DeliveryTypeEnum.ZX.getCode().equals(delivery) && SaleTypeEnum.Xs.getCode().equals(saleType)) {
            BusDept busDept = deptService.getById(deptId);
            BigDecimal saleAmount = orderDetails.getSalePrice().multiply(orderDetails.getSaleNum());
            //资信额度
            BigDecimal reputationAmount = busDept.getReputationAmount();
            ApiAssert.gtzero("资信额度未配置", reputationAmount);
            BigDecimal userReputationAmount = FlymeUtils.getBigDecimal(totalReputationAmount(deptId), "0");
            //总额度-已用额度-当前添加商品销售额
            BigDecimal noUserAmount = reputationAmount.subtract(userReputationAmount).subtract(saleAmount);
            ApiAssert.gezero("资信额度不足", noUserAmount);
        }
        BusDrugs drugs = drugsService.getById(orderDetails.getDrugsId());

        OrderDetailsVo orderDetailsVo = new OrderDetailsVo();


        //查询供货方费率配置
        BusSupplierRate supplierRate = supplierRateService.findOrderSupplierRate(orderDetails, busOrder);
        //查询购货方费率配置
        BusCustomRate customRate = customRateService.findCustomRate(orderDetails, busOrder);

        orderDetailsVo.setCustomRate(customRate);
        orderDetailsVo.setSupplierRate(supplierRate);
        orderDetails.setCustomRateId(customRate.getCustomRateId());
        orderDetails.setSupplierRateId(supplierRate.getSupplierRateId());
        orderDetailsVo.setBusOrder(busOrder);
        BigDecimal saleNum = orderDetails.getSaleNum();
        BigDecimal salePrice = orderDetails.getSalePrice();

        BigDecimal saleAmount = salePrice.multiply(saleNum);
        orderDetails.setSaleAmount(saleAmount);


        if (FlymeUtils.isEmpty(orderDetails.getSupplierTaxRate())) {
            //供货方垫付款费率
            orderDetails.setSupplierTaxRate(supplierRate.getSupplierTaxRate());
        }
        if (FlymeUtils.isEmpty(orderDetails.getSupplierSettleRate())) {
            //供货方结算费率
            orderDetails.setSupplierSettleRate(supplierRate.getSupplierSettleRate());
        }
        if (FlymeUtils.isEmpty(orderDetails.getHighTaxRateFormulaId())) {
            //供货方高开税金公式
            orderDetails.setHighTaxRateFormulaId(supplierRate.getHighTaxRateFormulaId());
        }
        if (FlymeUtils.isEmpty(orderDetails.getRefundFormulaId())) {
            //供货方返款公式
            orderDetails.setRefundFormulaId(supplierRate.getRefundFormulaId());
        }


        if (FlymeUtils.isEmpty(orderDetails.getCustomSettleGapUpTaxRate())) {
            //结算高开税金费率
            orderDetails.setCustomSettleGapUpTaxRate(customRate.getCustomSettleGapUpTaxRate());
        }
        if (FlymeUtils.isEmpty(orderDetails.getCustomSettleRate())) {
            //结算费率
            orderDetails.setCustomSettleRate(customRate.getCustomSettleRate());
        }
        if (FlymeUtils.isEmpty(orderDetails.getCustomTaxRate())) {
            //结算保证金费率
            orderDetails.setCustomTaxRate(customRate.getCustomTaxRate());
        }
        if (FlymeUtils.isEmpty(orderDetails.getSettleFormulaId())) {
            //结算公式
            orderDetails.setSettleFormulaId(customRate.getSettleFormulaId());
        }
        if (FlymeUtils.isNotEmpty(orderDetails.getSettleFormulaId2())) {
            //结算公式
            orderDetails.setSettleFormulaId2(orderDetails.getSettleFormulaId2());
        }

        Long supplierId = drugs.getSupplierId();
        //查询部门结算价(无配置取药品的结算价配置)
        BusCustomRate deptCustomRate = customRateService.findByDeptId(supplierId, drugsId, deptId);
        BigDecimal settlePrice = new BigDecimal("0");
        if (FlymeUtils.isNotEmpty(orderDetails.getSettlePrice()) && FlymeUtils.gtzero(orderDetails.getSettlePrice())) {
            //取录入的结算价
            settlePrice = orderDetails.getSettlePrice();
        }
        if (FlymeUtils.isNotEmpty(deptCustomRate)) {
            if (FlymeUtils.isEmpty(settlePrice) || FlymeUtils.lezero(settlePrice)) {
                settlePrice = FlymeUtils.getBigDecimal(deptCustomRate.getSettlePrice(), "0");
            }
            //设置结算价格
            orderDetails.setSettlePrice(settlePrice);
            //计算结算发货金额
            orderDetails.setSettleSendAmount(settlePrice.multiply(saleNum));
        }
        orderDetailsVo.setBusOrderDetails(orderDetails);
        Long drugsLotId = orderDetails.getDrugsLotId();
        //默认取全局成本价
        BigDecimal costPrice = FlymeUtils.getBigDecimal(drugs.getCostPrice(), "0");
        if (FlymeUtils.isNotEmpty(drugsLotId) && SaleTypeEnum.Xs.getCode().equals(saleType)) {
            BusDrugslot drugsLot = drugslotService.getById(drugsLotId);
            costPrice = drugsLot.getCostPrice();
        }
        if (FlymeUtils.isNotEmpty(orderDetails.getCostPrice())) {
            //取核算成本价
            costPrice = orderDetails.getCostPrice();
        }
        if (!SaleTypeEnum.Pz.getCode().equals(Integer.parseInt(saleType))) {
            ApiAssert.gtzero("成本价未配置", costPrice);
        }
        BigDecimal costAmount = costPrice.multiply(saleNum);

        //成本价
        orderDetails.setCostPrice(costPrice);
        //成本金额
        orderDetails.setCostAmount(costAmount);
        //供货方高开价(销售-成本)
        BigDecimal supplierGapUpPrice = salePrice.subtract(costPrice);
        //供货方高开金额(高开价格*数量)
        orderDetails.setSupplierGapUpAmount(supplierGapUpPrice.multiply(saleNum));
        //计算供货方高开税金(垫付款税金)
        BigDecimal supplierGapUpTaxesAmount = calculateSupplierGapUpTaxes(orderDetailsVo);
        orderDetails.setSupplierGapUpTaxesAmount(supplierGapUpTaxesAmount);
        //计算供货方应返金额
        BigDecimal supplierRetable = calculateSupplierRetable(orderDetailsVo);
        orderDetails.setSupplierRetable(supplierRetable);
        //必须设置结算价后再计算购货方保证金
        if (FlymeUtils.gtzero(settlePrice)) {
            //购货方底价计算方式1：按结算价 2:按成本价
            Integer floorPriceType = FlymeUtils.getInteger(drugs.getFloorPriceType(), 1);
            // 销售高开价格(销售-结算)
            BigDecimal customGapUpPrice = salePrice.subtract(settlePrice);
            //销售底价
            BigDecimal customFloorAmount = orderDetails.getSettleSendAmount();
            //底价方式采用成本价
            if (floorPriceType.equals(2)) {
                // 销售高开价格(销售-成本)
                customGapUpPrice = salePrice.subtract(costPrice);
                customFloorAmount = costAmount;
            }
            orderDetails.setCustomFloorAmount(customFloorAmount);
            //购货方高开金额
            BigDecimal customGapUpAmount = customGapUpPrice.multiply(saleNum);
            orderDetails.setCustomGapUpAmount(customGapUpAmount);
            // 销售结算高开税金费率
            BigDecimal customSettleGapUpTaxRate = FlymeUtils.getBigDecimal(orderDetails.getCustomSettleGapUpTaxRate(), customRate.getCustomSettleGapUpTaxRate());
            // 计算销售结算高开税金金额
            BigDecimal customSettleGapUpAmount = salePrice.subtract(settlePrice).multiply(saleNum).multiply(customSettleGapUpTaxRate);
            orderDetails.setCustomSettleGapUpAmount(customSettleGapUpAmount);

            // 计算销售保证金税金金额
            BigDecimal customGapUpTaxesAmount = calculateCustomGapUpRateAmount(orderDetailsVo);
            orderDetails.setCustomGapUpTaxesAmount(customGapUpTaxesAmount);

            //计算结算金额
            BigDecimal settleAmount = calculateSettleAmount(orderDetailsVo);
            orderDetails.setSettleAmount(settleAmount);
            if (FlymeUtils.isNotEmpty(settleType) && settleType) {
                //按流向结算金额
                BigDecimal settleAmount2 = calculateSettleAmount2(orderDetailsVo);
                orderDetails.setSettleAmount2(settleAmount2);

                //按流向结算金额
                BigDecimal settleAmount3 = calculateSettleAmount3(orderDetailsVo);
                orderDetails.setSettleAmount3(settleAmount3);
            }
            //公司利润
            BigDecimal profitAmount = calculateProfitAmount(orderDetailsVo);
            orderDetails.setProfitAmount(profitAmount);
        }
        calculateCustomBondByHeSuan(orderDetails, busOrder, old.getRadio());
        //计算供货方垫付款
        calculateSupplierBondByHesuan(orderDetails, busOrder);
        //票折订单核算
        if (SaleTypeEnum.Pz.getCode().equals(Integer.parseInt(saleType))) {
            orderDetails.setCostPrice(new BigDecimal("0"));
            orderDetails.setCostAmount(new BigDecimal("0"));
            orderDetails.setCustomBond(new BigDecimal("0"));
            orderDetails.setSalePrice(new BigDecimal("0"));
            orderDetails.setSaleNum(new BigDecimal("0"));
            orderDetails.setSupplierBond(new BigDecimal("0"));
            orderDetails.setSettleSendAmount(new BigDecimal("0"));
            orderDetails.setReturnAmount(orderDetails.getSaleAmount());
            // 销售结算高开税金费率
            BigDecimal customSettleGapUpTaxRate = FlymeUtils.getBigDecimal(orderDetails.getCustomSettleGapUpTaxRate(), customRate.getCustomSettleGapUpTaxRate());
            // 计算销售结算高开税金金额
            BigDecimal customSettleGapUpAmount = orderDetails.getSaleAmount().multiply(customSettleGapUpTaxRate);
            orderDetails.setCustomSettleGapUpAmount(customSettleGapUpAmount);
        }
    }


    private BigDecimal initDiscountDetails(BusOrderDetails orderDetails, BigDecimal discountAmount) {
        //折扣价
        BigDecimal discountPrice = orderDetails.getDiscountPrice();


        return null;
    }


    /**
     * 计算供货方高开税金(参与垫付款计算)
     *
     * @param orderDetailsVo
     * @return
     */
    private BigDecimal calculateSupplierGapUpTaxes(OrderDetailsVo orderDetailsVo) {
        BusOrderDetails orderDetails = orderDetailsVo.getBusOrderDetails();
        BigDecimal supplierGapUpTaxesAmount = new BigDecimal("0");
        String highTaxRateFormulaContent = orderDetails.getHighTaxRateFormulaContent();
        if (FlymeUtils.isEmpty(highTaxRateFormulaContent)) {
            Long highTaxRateFormulaId = orderDetails.getHighTaxRateFormulaId();
            ApiAssert.isNotEmpty("高开税金公式未配置", highTaxRateFormulaId);
            // 高开税金公式
            SysFormula sysFormula = sysFormulaService.getById(highTaxRateFormulaId);
            ApiAssert.isNotEmpty("高开税金公式不存在", sysFormula);
            highTaxRateFormulaContent = sysFormula.getFormulaContent();
        }
        try {
            Map<String, Object> variable = orderDetailsVo.getVariable();
            supplierGapUpTaxesAmount = groovyScriptEngine.executeBigDecimal(highTaxRateFormulaContent, variable);
        } catch (Exception e) {
            e.printStackTrace();
            ApiAssert.failure("供货方高开税金计算异常");
        }

        return supplierGapUpTaxesAmount;
    }


    /**
     * 计算供货方应返金额
     *
     * @param orderDetailsVo
     * @return
     */
    private BigDecimal calculateSupplierRetable(OrderDetailsVo orderDetailsVo) {
        BusOrderDetails orderDetails = orderDetailsVo.getBusOrderDetails();
        BigDecimal supplierRetable = new BigDecimal("0");
        Long refundFormulaId = orderDetails.getRefundFormulaId();
        String refundFormulaContent = orderDetails.getRefundFormulaContent();
        if (FlymeUtils.isEmpty(refundFormulaContent)) {
            ApiAssert.isNotEmpty("返款公式未配置", refundFormulaId);
            // 查询返款公式
            SysFormula sysFormula = sysFormulaService.getById(refundFormulaId);
            ApiAssert.isNotEmpty("返款公式不存在", sysFormula);
            refundFormulaContent = sysFormula.getFormulaContent();
        }
        try {
            Map<String, Object> variable = orderDetailsVo.getVariable();
            supplierRetable = groovyScriptEngine.executeBigDecimal(refundFormulaContent, variable);
        } catch (Exception e) {
            e.printStackTrace();
            ApiAssert.failure("供货方应返金额计算异常");
        }

        return supplierRetable;
    }


    /**
     * 计算市场结算金额
     *
     * @param orderDetailsVo
     * @return
     */
    private BigDecimal calculateSettleAmount(OrderDetailsVo orderDetailsVo) {
        BusOrderDetails orderDetails = orderDetailsVo.getBusOrderDetails();
        BigDecimal settleAmount = new BigDecimal("0");

        Long settleFormulaId = orderDetails.getSettleFormulaId();
        String settleFormulaContent = orderDetails.getSettleFormulaContent();
        if (FlymeUtils.isEmpty(settleFormulaContent)) {
            ApiAssert.isNotEmpty("结算公式未配置", settleFormulaId);
            // 查询结算公式
            SysFormula sysFormula = sysFormulaService.getById(settleFormulaId);
            ApiAssert.isNotEmpty("结算公式不存在", sysFormula);
            settleFormulaContent = sysFormula.getFormulaContent();
        }
        try {
            Map<String, Object> variable = orderDetailsVo.getVariable();
            settleAmount = groovyScriptEngine.executeBigDecimal(settleFormulaContent, variable);
        } catch (Exception e) {
            e.printStackTrace();
            ApiAssert.failure("结算金额计算异常");
        }

        return settleAmount;
    }

    /**
     * 计算市场结算金额
     *
     * @param orderDetailsVo
     * @return
     */
    private BigDecimal calculateSettleAmount2(OrderDetailsVo orderDetailsVo) {
        BusOrderDetails orderDetails = orderDetailsVo.getBusOrderDetails();
        BigDecimal settleAmount = new BigDecimal("0");
        Long settleFormulaId2 = orderDetails.getSettleFormulaId2();
        if (FlymeUtils.isNotEmpty(settleFormulaId2)) {
            try {
                // 查询结算公式
                SysFormula sysFormula = sysFormulaService.getById(settleFormulaId2);
                ApiAssert.isNotEmpty("结算公式不存在", sysFormula);
                String settleFormulaContent = sysFormula.getFormulaContent();
                Map<String, Object> variable = orderDetailsVo.getVariable();
                settleAmount = groovyScriptEngine.executeBigDecimal(settleFormulaContent, variable);
            } catch (Exception e) {
                e.printStackTrace();
                ApiAssert.failure("结算金额计算异常");
            }
        }

        return settleAmount;
    }

    /**
     * 计算市场结算金额
     *
     * @param orderDetailsVo
     * @return
     */
    private BigDecimal calculateSettleAmount3(OrderDetailsVo orderDetailsVo) {
        BusOrderDetails orderDetails = orderDetailsVo.getBusOrderDetails();
        BigDecimal settleAmount = new BigDecimal("0");
        Long settleFormulaId3 = orderDetails.getSettleFormulaId3();
        if (FlymeUtils.isNotEmpty(settleFormulaId3)) {
            try {
                // 查询结算公式
                SysFormula sysFormula = sysFormulaService.getById(settleFormulaId3);
                ApiAssert.isNotEmpty("结算公式不存在", sysFormula);
                String settleFormulaContent = sysFormula.getFormulaContent();
                Map<String, Object> variable = orderDetailsVo.getVariable();
                settleAmount = groovyScriptEngine.executeBigDecimal(settleFormulaContent, variable);
            } catch (Exception e) {
                e.printStackTrace();
                ApiAssert.failure("结算金额计算异常");
            }
        }

        return settleAmount;
    }


    /**
     * 计算利润
     *
     * @param orderDetailsVo
     * @return
     */
    private BigDecimal calculateProfitAmount(OrderDetailsVo orderDetailsVo) {
        BusOrderDetails orderDetails = orderDetailsVo.getBusOrderDetails();
        BigDecimal profitAmount = new BigDecimal("0");
        Long profitAmountFormulaId = orderDetails.getProfitAmountFormulaId();
        String profitAmountFormulaContent = orderDetails.getProfitAmountFormulaContent();
        if (FlymeUtils.isNotEmpty(profitAmountFormulaId) || FlymeUtils.isNotEmpty(profitAmountFormulaContent)) {
            if (FlymeUtils.isEmpty(profitAmountFormulaContent)) {
                // 查询利润公式
                SysFormula sysFormula = sysFormulaService.getById(profitAmountFormulaId);
                ApiAssert.isNotEmpty("利润公式不存在", sysFormula);
                profitAmountFormulaContent = sysFormula.getFormulaContent();
            }
            try {
                Map<String, Object> variable = orderDetailsVo.getVariable();
                profitAmount = groovyScriptEngine.executeBigDecimal(profitAmountFormulaContent, variable,2);
            } catch (Exception e) {
                e.printStackTrace();
                ApiAssert.failure("结算金额计算异常");
            }

        } else {
            BigDecimal setleAmount2 = FlymeUtils.getBigDecimal(orderDetails.getSettleAmount2(), "0");
            BigDecimal setleAmount3 = FlymeUtils.getBigDecimal(orderDetails.getSettleAmount3(), "0");
            profitAmount = orderDetails.getSupplierRetable().subtract(orderDetails.getSettleAmount().add(setleAmount2).add(setleAmount3));
            orderDetails.setProfitAmount(profitAmount);
        }
        return profitAmount;
    }

    private void calculateCustomBondByAdd(BusOrderDetails orderDetails, BusOrder busOrder) {
        //购货方资信方式
        Integer customBondType = busOrder.getCustomBondType();
        ApiAssert.isNotEmpty("购货方资信方式不能为空", customBondType);
        BigDecimal customOverBond = orderDetails.getCustomOverBond();
        if (customBondType > 0 && !customBondType.equals(5) && !customBondType.equals(7)) {
            //保证金
            BigDecimal customBond = new BigDecimal("0");
            //底价
            BigDecimal floorAmount = FlymeUtils.getBigDecimal(orderDetails.getCustomFloorAmount(), "0");
            //税金
            BigDecimal customGapUpTaxesAmount = FlymeUtils.getBigDecimal(orderDetails.getCustomGapUpTaxesAmount(), "0");
            if (customBondType.equals(1)) {
                customBond = floorAmount;
            }
            if (customBondType.equals(3) || customBondType.equals(2) || customBondType.equals(6)) {
                if (customBondType.equals(3)) {
                    customBond = customGapUpTaxesAmount;
                }
                if (customBondType.equals(2)) {
                    customBond = floorAmount.add(customGapUpTaxesAmount);
                }
                if (customBondType.equals(6)) {
                    customBond = floorAmount.divide(new BigDecimal("2")).add(customGapUpTaxesAmount);
                }
            }
            BigDecimal takeAmount = busOrder.getTakeAmount();
            //添加或者修改订单明细更新订单多收金额
            BigDecimal overTakeAmount = takeAmount.subtract(customBond);
            orderDetails.setCustomOverBond(overTakeAmount);
            orderDetails.setCustomBond(customBond);
        } else {
            //删除资保金
            orderDetails.setCustomBond(new BigDecimal("0"));
        }
    }

    private void calculateCustomBondByHeSuan(BusOrderDetails orderDetails, BusOrder busOrder, BigDecimal ratio) {
        //购货方资信方式
        Integer customBondType = busOrder.getCustomBondType();
        ApiAssert.isNotEmpty("购货方资信方式不能为空", customBondType);
        BigDecimal customOverBond = orderDetails.getCustomOverBond();
        if (customBondType > 0 && !customBondType.equals(5) && !customBondType.equals(7)) {
            //保证金
            BigDecimal customBond = new BigDecimal("0");
            //底价
            BigDecimal floorAmount = FlymeUtils.getBigDecimal(orderDetails.getCustomFloorAmount(), "0");
            //税金
            BigDecimal customGapUpTaxesAmount = FlymeUtils.getBigDecimal(orderDetails.getCustomGapUpTaxesAmount(), "0");
            if (customBondType.equals(1)) {
                customBond = floorAmount;
            }
            if (customBondType.equals(3) || customBondType.equals(2) || customBondType.equals(6)) {
                if (customBondType.equals(3)) {
                    customBond = customGapUpTaxesAmount;
                }
                if (customBondType.equals(2)) {
                    customBond = floorAmount.add(customGapUpTaxesAmount);
                }
                if (customBondType.equals(6)) {
                    customBond = floorAmount.divide(new BigDecimal("2")).add(customGapUpTaxesAmount);
                }
            }
            orderDetails.setCustomBond(customBond);
            if (FlymeUtils.allNotNull(customOverBond, ratio)) {
                //修改订单重新计算保证金
                orderDetails.setCustomOverBond(customOverBond.multiply(ratio).setScale(2, BigDecimal.ROUND_HALF_UP));
                orderDetails.setCustomBond(customBond.multiply(ratio).setScale(2, BigDecimal.ROUND_HALF_UP));
            } else {
                BigDecimal takeAmount = busOrder.getTakeAmount();
                BigDecimal overAmount = takeAmount.subtract(customBond);
                orderDetails.setCustomOverBond(overAmount);
            }

        } else {
            //删除资保金
            orderDetails.setCustomBond(new BigDecimal("0"));
        }

    }


    /**
     * 计算购货方保证金高开税金(参与市场保证金计算)
     *
     * @param orderDetailsVo
     * @return
     */
    private BigDecimal calculateCustomGapUpRateAmount(OrderDetailsVo orderDetailsVo) {
        BusOrderDetails orderDetails = orderDetailsVo.getBusOrderDetails();
        BigDecimal customGapUpRateAmount = new BigDecimal("0");
        //保证金费率
        BigDecimal customTaxRate = orderDetails.getCustomTaxRate();
        //保证金高开金额
        BigDecimal customGapUpAmount = orderDetails.getCustomGapUpAmount();
        customGapUpRateAmount = customGapUpAmount.multiply(customTaxRate);
        return customGapUpRateAmount;
    }

    /**
     * 根据订单ID查询订单明细
     *
     * @param orderId
     * @return
     */
    @Override
    public List<BusOrderDetails> selectByOrderId(Long orderId) {
        CriteriaQuery cq = new CriteriaQuery(BusOrderDetails.class);
        cq.eq(true, "orderId", orderId);
        cq.eq(true, "orderDetailsState", CommonConstants.ENABLED);
        return list(cq);
    }

    /**
     * 根据订单ID查询订单明细
     *
     * @param orderId
     * @return
     */
    @Override
    public List<BusOrderDetails> selectByOrderId(Long orderId, SaleTypeEnum saleType) {
        CriteriaQuery cq = new CriteriaQuery(BusOrderDetails.class);
        cq.eq(true, "orderId", orderId);
        cq.eq(true, "orderDetailsState", CommonConstants.ENABLED);
        cq.eq(true, "saleType", saleType.getCode());
        return list(cq);
    }

    /**
     * 根据parentId查询订单明细
     *
     * @return
     */
    @Override
    public BusOrderDetails selectByParentId(Long parentId, SaleTypeEnum saleType) {
        CriteriaQuery cq = new CriteriaQuery(BusOrderDetails.class);
        cq.eq(true, "parentId", parentId);
        cq.eq(true, "saleType", saleType.getCode());
        cq.eq(true, "orderDetailsState", CommonConstants.ENABLED);
        return getOne(cq, false);
    }


    /**
     * 根据订单ID删除订单明细
     *
     * @param orderId
     * @return
     */
    @Override
    public Boolean delByOrderId(Serializable orderId) {
        CriteriaDelete cd = new CriteriaDelete();
        cd.eq(true, "orderId", orderId);
        return remove(cd);
    }


    /**
     * 更新订单后重新计算相关金额
     *
     * @param busOrder
     * @return
     */
    @Override
    public void updateByOrder(BusOrder busOrder) {
        Long orderId = busOrder.getOrderId();
        List<BusOrderDetails> list = selectByOrderId(orderId);
        if (FlymeUtils.isNotEmpty(list)) {
            if (list.size() == 1) {
                BusOrderDetails orderDetails = list.get(0);
                //计算订单相关金额
                calculateSaleAmount(orderDetails, new EntityMap());
                //计算垫付款
                calculateSupplierBond(orderDetails, busOrder);
                //更新订单明细
                updateById(orderDetails);
                Integer delivery = busOrder.getDelivery();
                if (delivery.equals(2)) {

                    //添加认款单
                    paymentService.addCustomBondPayment(busOrder);
                } else {
                    //删除认款单
                    paymentService.removeByOrderId(AmountTypeEnum.CustomBond, orderId.toString());
                }
            }
        }
    }

    @Override
    public ResultBody afterDelete(CriteriaDelete cd, Serializable[] ids) {
        Serializable orderDetailsId = cd.getIdValue();
        //删除保证金认款单
        paymentService.getByOrderDetailsIdAndAmountType(orderDetailsId.toString(), AmountTypeEnum.CustomBond);
        return super.afterDelete(cd, ids);
    }


    @Override
    public BigDecimal totalSaleAmount(Long orderId) {
        CriteriaQuery<BusOrderDetails> cq = new CriteriaQuery(BusOrderDetails.class);
        cq.select("sum(saleAmount)");
        cq.eq("orderDetailsState", CommonConstants.ENABLED);
        cq.eq(true, "orderId", orderId);
        BigDecimal amount = getObj(cq, e -> new BigDecimal(e.toString()));
        return FlymeUtils.getBigDecimal(amount, new BigDecimal("0"));
    }

    @Override
    public List<EntityMap> getOrderDetails(Long orderId) {
        CriteriaQuery cq = new CriteriaQuery(BusOrderDetails.class);
        cq.select(BusOrderDetails.class, "saleNum", "salePrice", "saleAmount", "companyId");
        cq.select(BusDrugs.class, "drugsName", "drugsSpec");
        cq.addSelect(BusDrugslot.class, "drugsLotNo");
        cq.eq(BusOrderDetails.class, "orderId", orderId);
        cq.eq(BusOrderDetails.class, "orderDetailsState", CommonConstants.ENABLED);
        cq.orderByDesc("bod.createTime");
        cq.createJoin(BusSupplier.class);
        cq.createJoin(BusDrugs.class);
        cq.createJoin(BusOrder.class);
        cq.createJoin(BusDrugslot.class);
        return selectEntityMap(cq);
    }


    /**
     * 查询已用额度
     */
    @Override
    public BigDecimal totalReputationAmount(Long deptId) {
        CriteriaQuery<BusOrderDetails> cq = new CriteriaQuery(BusOrderDetails.class);
        cq.select("sum(saleAmount) saleAmount");
        //资信发货
        cq.eq(BusOrder.class, "delivery", 2);
        //未返款或者返款未审批
        cq.and(e -> e.isNull("bod.customReturnState").or().ne("bod.customReturnState", 2));
        cq.eq(true, "bod.deptId", deptId);
        cq.eq(BusOrderDetails.class, "orderDetailsState", CommonConstants.ENABLED);
        cq.createJoin(BusOrder.class);
        EntityMap map = findOne(cq);
        if (FlymeUtils.isNotEmpty(map)) {
            return map.getBigDecimal("saleAmount");
        } else {
            return new BigDecimal("0");
        }
    }

    @Override
    public ResultBody chaiFen(OrderCustomReturn bocr, String fileIds) {
        Long orderDetailsId = bocr.getOrderDetailsId();
        BusOrderDetails orderDetails = getById(orderDetailsId);
        ApiAssert.isNotEmpty("orderDetails不能为空", orderDetails);
        //父明细ID
        Long parentId = orderDetails.getParentId();
        Long orderId = orderDetails.getOrderId();
        BusOrder busOrder = orderService.getById(orderId);
        if (FlymeUtils.isNotEmpty(parentId)) {
            chaiFenByChild(bocr, busOrder, orderDetails);
        } else {
            chaiFenByParent(bocr, orderDetails);
        }
        return ResultBody.ok();
    }

    /**
     * 当父订单ID不为空时
     *
     * @param bocr
     */
    private void chaiFenByChild(OrderCustomReturn bocr, BusOrder busOrder, BusOrderDetails orderDetails) {
        Long orderDetailsId = bocr.getOrderDetailsId();
        ApiAssert.isNotEmpty("orderDetails不能为空", orderDetails);
        BigDecimal salePrice = orderDetails.getSalePrice();
        //销售金额
        BigDecimal saleAmount = orderDetails.getSaleAmount();
        //销售数量
        BigDecimal saleNum = orderDetails.getSaleNum();
        BigDecimal oldRadio = FlymeUtils.getBigDecimal(orderDetails.getRadio(), "1");

        //拆分数量
        BigDecimal chaiFenNum = FlymeUtils.getBigDecimal(bocr.getReturnNum(), "0");

        BigDecimal chaiFenAmount = FlymeUtils.getBigDecimal(bocr.getReturnAmount(), "0");
        //父明细ID
        Long parentId = orderDetails.getParentId();

        BusOrderDetails parent = getById(parentId);
        BigDecimal totalSaleNum = parent.getSaleNum();
        BigDecimal totalSaleAmount = parent.getSaleAmount();

        //回款方式1按数量 2按金额
        Integer returnType = bocr.getReturnType();
        BigDecimal ratio = new BigDecimal("1");
        BigDecimal ratio1 = new BigDecimal("1");
        //按数量
        if (returnType.equals(1)) {
            //计算回款比例
            ratio = chaiFenNum.divide(totalSaleNum, 3, BigDecimal.ROUND_HALF_UP);
            ratio1 = chaiFenNum.divide(saleNum, 3, BigDecimal.ROUND_HALF_UP);
            //计算拆分金额
            chaiFenAmount = chaiFenNum.multiply(salePrice);
        }
        //按金额
        if (returnType.equals(2)) {
            //计算回款比例(相对总订单的比例)
            ratio = chaiFenAmount.divide(totalSaleAmount, 3, BigDecimal.ROUND_HALF_UP);

            ratio1 = chaiFenAmount.divide(saleAmount, 3, BigDecimal.ROUND_HALF_UP);
            //计算回款数量
            chaiFenNum = totalSaleNum.multiply(ratio).setScale(3, BigDecimal.ROUND_HALF_UP);
        }

        //拆出新明细
        BusOrderDetails newOrderDetails = addOrderDetails(orderDetails, busOrder, chaiFenNum, chaiFenAmount, ratio, ratio1);
        //剩余数量
        BigDecimal surplusNum = saleNum.subtract(chaiFenNum);
        BigDecimal surplusAmount = saleAmount.subtract(chaiFenAmount);
        //当前拆分对象明细分费率-拆出费率
        BigDecimal surplusRadio = oldRadio.subtract(ratio);
        //更新老明细
        updateOrderDetails(newOrderDetails, orderDetails, surplusNum, surplusRadio);

    }


    private void chaiFenByParent(OrderCustomReturn bocr, BusOrderDetails orderDetails) {
        Long orderDetailsId = bocr.getOrderDetailsId();
        ApiAssert.isNotEmpty("orderDetails不能为空", orderDetails);
        Long orderId = orderDetails.getOrderId();
        BusOrder busOrder = orderService.getById(orderId);
        BigDecimal salePrice = orderDetails.getSalePrice();
        //销售金额
        BigDecimal saleAmount = orderDetails.getSaleAmount();
        //销售数量
        BigDecimal saleNum = orderDetails.getSaleNum();
        BigDecimal oldRadio = FlymeUtils.getBigDecimal(orderDetails.getRadio(), "1");
        //销售数量
        BigDecimal totalSaleNum = orderDetails.getSaleNum();

        BigDecimal totalSaleAmount = orderDetails.getSaleAmount();

        //父明细ID
        Long parentId = orderDetails.getParentId();
        //拆分数量
        BigDecimal chaiFenNum = FlymeUtils.getBigDecimal(bocr.getReturnNum(), "0");

        BigDecimal chaiFenAmount = FlymeUtils.getBigDecimal(bocr.getReturnAmount(), "0");
        //回款方式1按数量 2按金额
        Integer returnType = bocr.getReturnType();
        //相对于父订单比例
        BigDecimal ratio = new BigDecimal("1");
        //相对于当前拆分比例
        BigDecimal ratio1 = new BigDecimal("1");
        //按数量
        if (returnType.equals(1)) {
            //计算回款比例
            ratio = chaiFenNum.divide(totalSaleNum, 3, BigDecimal.ROUND_HALF_UP);
            //计算拆分金额
            chaiFenAmount = chaiFenNum.multiply(salePrice);
        }
        //按金额
        if (returnType.equals(2)) {
            //计算回款比例
            ratio = chaiFenAmount.divide(totalSaleAmount, 3, BigDecimal.ROUND_HALF_UP);
            //计算回款数量
            chaiFenNum = totalSaleNum.multiply(ratio).setScale(3, BigDecimal.ROUND_HALF_UP);
        }

        //拆出新明细
        BusOrderDetails newOrderDetails = addOrderDetailsByParent(orderDetails, busOrder, chaiFenNum, ratio);
        //剩余数量
        BigDecimal surplusNum = saleNum.subtract(chaiFenNum);
        BigDecimal surplusAmount = saleAmount.subtract(chaiFenAmount);
        //当前拆分对象明细分费率-拆出费率
        BigDecimal surplusRadio = oldRadio.subtract(ratio);
        //拆出新明细
        addOrderDetailsByParent2(orderDetails, busOrder, newOrderDetails, surplusNum, surplusRadio);

        //更新原订单为已禁用
        updateOrderDetailsState(orderId, orderDetails, CommonConstants.DISABLED);
    }


    /**
     * 退货补货
     *
     * @param orderDetailsId 原订单明细ID
     * @param saleType       类型(2:退货，3补货)
     * @param saleNum        数量
     * @param saleDate       日期
     */
    @Override
    public ResultBody addReturnOrderDetails(Long orderDetailsId, Integer saleType, BigDecimal saleNum, String saleDate) {
        //查询原订单明细
        BusOrderDetails orderDetails = getById(orderDetailsId);
        BusOrder order = null;
        //订单ID
        Long orderId = null;
        if (saleType.equals(SaleTypeEnum.Bh.getCode())) {
            //补货用原订单ID
            BusOrderDetails details = getById(orderDetails.getParentId());
            //查询原来订单
            order = orderService.getById(details.getOrderId());
            orderId = order.getOrderId();
        } else {
            //订单ID
            orderId = orderDetails.getOrderId();
            //查询原来订单
            order = orderService.getById(orderId);
        }
        BusOrder newOrder = new BusOrder();
        BeanUtils.copyProperties(order, newOrder);
        newOrder.setProcessInstanceId(null);
        newOrder.setOrderId(IdWorker.getId());
        Long compayId = orderDetails.getCompanyId();
        if (compayId.equals(1L)) {
            newOrder.setOrderState(CommonConstants.INT_0);
        } else {
            //朗迪退货直接审批通过
            newOrder.setOrderState(CommonConstants.INT_2);
        }
        newOrder.setTakeDate(order.getTakeDate());
        newOrder.setParentId(orderId);
        newOrder.setTakeDate(null);
        newOrder.setTakeAmount(new BigDecimal("0"));
        newOrder.setCreateTime(DateUtils.getNowDateTime());
        newOrder.setUpdateTime(DateUtils.getNowDateTime());
        newOrder.setSendDate(DateUtils.parseDate(saleDate));

        if (saleType.equals(SaleTypeEnum.Th.getCode())) {
            //退货取负值
            saleNum = saleNum.multiply(new BigDecimal("-1"));
            newOrder.setOrderType(SaleTypeEnum.Th.getCode());
            newOrder.setOrderNo("T" + order.getOrderNo());
        } else {
            newOrder.setOrderNo("B" + order.getOrderNo());
            newOrder.setOrderType(SaleTypeEnum.Bh.getCode());
        }
        //全款资信
        Integer delivery = order.getDelivery();
        orderDetails.setOrderId(newOrder.getOrderId());
        if (delivery.equals(1)) {
            //全款订单退货
            addTuiHuoOrderDetails(orderDetails, saleNum, saleDate);
        } else {
            //资信退货
            addTuiHuoOrderDetails(orderDetails, saleNum, saleDate);
        }
        orderService.save(newOrder);
        return ResultBody.ok();
    }


    /**
     * 更新拆单
     *
     * @param orderDetailsId 原订单明细ID
     * @param returnNum      销售数量
     * @param surplusAmount  销售金额
     * @param orderDetails   操作对象
     * @param orderDetailsId 主键
     * @param ratio          拆单比例
     */
    private BusOrderDetails updateOrderDetails(BusOrderDetails newOrderDetails, BusOrderDetails orderDetails, BigDecimal returnNum, BigDecimal ratio) {
        //更新老明细
        orderDetails.setRadio(ratio);
        orderDetails.setSaleNum(returnNum);

        BigDecimal settleAmount = FlymeUtils.getBigDecimal(orderDetails.getSettleAmount(), "0");
        BigDecimal settleAmount1 = FlymeUtils.getBigDecimal(newOrderDetails.getSettleAmount(), "0");
        orderDetails.setSettleAmount(settleAmount.subtract(settleAmount1));

        BigDecimal settleAmount2 = FlymeUtils.getBigDecimal(orderDetails.getSettleAmount2(), "0");
        BigDecimal newSettleAmount2 = FlymeUtils.getBigDecimal(newOrderDetails.getSettleAmount2(), "0");
        orderDetails.setSettleAmount2(settleAmount2.subtract(newSettleAmount2));

        BigDecimal settleAmount3 = FlymeUtils.getBigDecimal(orderDetails.getSettleAmount3(), "0");
        BigDecimal newSettleAmount3 = FlymeUtils.getBigDecimal(newOrderDetails.getSettleAmount3(), "0");
        orderDetails.setSettleAmount3(settleAmount3.subtract(newSettleAmount3));


        BigDecimal saleAmount = FlymeUtils.getBigDecimal(orderDetails.getSaleAmount(), "0");
        BigDecimal saleAmount1 = FlymeUtils.getBigDecimal(newOrderDetails.getSaleAmount(), "0");
        orderDetails.setSaleAmount(saleAmount.subtract(saleAmount1));


        BigDecimal costAmount = FlymeUtils.getBigDecimal(orderDetails.getCostAmount(), "0");
        BigDecimal costAmount1 = FlymeUtils.getBigDecimal(newOrderDetails.getCostAmount(), "0");
        orderDetails.setCostAmount(costAmount.subtract(costAmount1));

        BigDecimal settleSendAmount = FlymeUtils.getBigDecimal(orderDetails.getSettleSendAmount(), "0");
        BigDecimal settleSendAmount1 = FlymeUtils.getBigDecimal(newOrderDetails.getSettleSendAmount(), "0");
        orderDetails.setSettleSendAmount(settleSendAmount.subtract(settleSendAmount1));


        BigDecimal customFloorAmount = FlymeUtils.getBigDecimal(orderDetails.getCustomFloorAmount(), "0");
        BigDecimal customFloorAmount1 = FlymeUtils.getBigDecimal(newOrderDetails.getCustomFloorAmount(), "0");
        orderDetails.setCustomFloorAmount(customFloorAmount.subtract(customFloorAmount1));

        BigDecimal supplierGapUpAmount = FlymeUtils.getBigDecimal(orderDetails.getSupplierGapUpAmount(), "0");
        BigDecimal supplierGapUpAmount1 = FlymeUtils.getBigDecimal(newOrderDetails.getSupplierGapUpAmount(), "0");
        orderDetails.setSupplierGapUpAmount(supplierGapUpAmount.subtract(supplierGapUpAmount1));

        BigDecimal supplierRetable = FlymeUtils.getBigDecimal(orderDetails.getSupplierRetable(), "0");
        BigDecimal supplierRetable1 = FlymeUtils.getBigDecimal(newOrderDetails.getSupplierRetable(), "0");
        orderDetails.setSupplierRetable(supplierRetable.subtract(supplierRetable1));

        BigDecimal supplierBond = FlymeUtils.getBigDecimal(orderDetails.getSupplierBond(), "0");
        BigDecimal supplierBond1 = FlymeUtils.getBigDecimal(newOrderDetails.getSupplierBond(), "0");
        orderDetails.setSupplierBond(supplierBond.subtract(supplierBond1));

        BigDecimal supplierPayBond = FlymeUtils.getBigDecimal(orderDetails.getSupplierPayBond(), "0");
        BigDecimal supplierPayBond1 = FlymeUtils.getBigDecimal(newOrderDetails.getSupplierPayBond(), "0");
        orderDetails.setSupplierPayBond(supplierPayBond.subtract(supplierPayBond1));


        BigDecimal supplierGapUpTaxesAmount = FlymeUtils.getBigDecimal(orderDetails.getSupplierGapUpTaxesAmount(), "0");
        BigDecimal supplierGapUpTaxesAmount1 = FlymeUtils.getBigDecimal(newOrderDetails.getSupplierGapUpTaxesAmount(), "0");
        orderDetails.setSupplierGapUpTaxesAmount(supplierGapUpTaxesAmount.subtract(supplierGapUpTaxesAmount1));

        BigDecimal customGapUpAmount = FlymeUtils.getBigDecimal(orderDetails.getCustomGapUpAmount(), "0");
        BigDecimal customGapUpAmount1 = FlymeUtils.getBigDecimal(newOrderDetails.getCustomGapUpAmount(), "0");
        orderDetails.setCustomGapUpAmount(customGapUpAmount.subtract(customGapUpAmount1));

        BigDecimal customGapUpTaxesAmount = FlymeUtils.getBigDecimal(orderDetails.getCustomGapUpTaxesAmount(), "0");
        BigDecimal customGapUpTaxesAmount1 = FlymeUtils.getBigDecimal(newOrderDetails.getCustomGapUpTaxesAmount(), "0");
        orderDetails.setCustomGapUpTaxesAmount(customGapUpTaxesAmount.subtract(customGapUpTaxesAmount1));


        BigDecimal customSettleGapUpAmount = FlymeUtils.getBigDecimal(orderDetails.getCustomSettleGapUpAmount(), "0");
        BigDecimal customSettleGapUpAmount1 = FlymeUtils.getBigDecimal(newOrderDetails.getCustomSettleGapUpAmount(), "0");
        orderDetails.setCustomSettleGapUpAmount(customSettleGapUpAmount.subtract(customSettleGapUpAmount1));


        BigDecimal profitAmount = FlymeUtils.getBigDecimal(orderDetails.getProfitAmount(), "0");
        BigDecimal profitAmount1 = FlymeUtils.getBigDecimal(newOrderDetails.getProfitAmount(), "0");
        orderDetails.setProfitAmount(profitAmount.subtract(profitAmount1));

        BigDecimal customBond = FlymeUtils.getBigDecimal(orderDetails.getCustomBond(), "0");
        BigDecimal customBond1 = FlymeUtils.getBigDecimal(newOrderDetails.getCustomBond(), "0");
        orderDetails.setCustomBond(customBond.subtract(customBond1));

        BigDecimal customOverBond = FlymeUtils.getBigDecimal(orderDetails.getCustomOverBond(), "0");
        BigDecimal customOverBond1 = FlymeUtils.getBigDecimal(newOrderDetails.getCustomOverBond(), "0");
        orderDetails.setCustomOverBond(customOverBond.subtract(customOverBond1));

        BigDecimal customYsk = FlymeUtils.getBigDecimal(orderDetails.getCustomYsk(), "0");
        BigDecimal customYsk1 = FlymeUtils.getBigDecimal(newOrderDetails.getCustomYsk(), "0");
        orderDetails.setCustomYsk(customYsk.subtract(customYsk1));

        BigDecimal returnAmount = FlymeUtils.getBigDecimal(orderDetails.getReturnAmount(), "0");
        BigDecimal returnAmount1 = FlymeUtils.getBigDecimal(newOrderDetails.getReturnAmount(), "0");
        orderDetails.setReturnAmount(returnAmount.subtract(returnAmount1));

        BigDecimal returnCustomBond = FlymeUtils.getBigDecimal(orderDetails.getReturnCustomBond(), "0");
        BigDecimal returnCustomBond1 = FlymeUtils.getBigDecimal(newOrderDetails.getReturnCustomBond(), "0");
        orderDetails.setReturnCustomBond(returnCustomBond.subtract(returnCustomBond1));

        BigDecimal returnSupplierBond = FlymeUtils.getBigDecimal(orderDetails.getReturnSupplierBond(), "0");
        BigDecimal returnSupplierBond1 = FlymeUtils.getBigDecimal(newOrderDetails.getReturnSupplierBond(), "0");
        orderDetails.setReturnSupplierBond(returnSupplierBond.subtract(returnSupplierBond1));

        BigDecimal invoiceAmount = FlymeUtils.getBigDecimal(orderDetails.getInvoiceAmount(), "0");
        BigDecimal invoiceAmount1 = FlymeUtils.getBigDecimal(newOrderDetails.getInvoiceAmount(), "0");
        orderDetails.setInvoiceAmount(invoiceAmount.subtract(invoiceAmount1));


        orderDetails.setSupplierBondPayDate(orderDetails.getSupplierBondPayDate());
        orderDetails.setDianfuId(orderDetails.getDianfuId());
        orderDetails.setRenkuanDate(orderDetails.getRenkuanDate());
        orderDetails.setSettleState(orderDetails.getSettleState());
        orderDetails.setSettleState2(orderDetails.getSettleState2());
        if (FlymeUtils.isNotEmpty(orderDetails.getSettleRealAmount())) {
            BigDecimal settleRealAmount1 = FlymeUtils.getBigDecimal(orderDetails.getSettleRealAmount(), "0");
            BigDecimal newSettleRealAmount1 = FlymeUtils.getBigDecimal(newOrderDetails.getSettleRealAmount(), "0");
            orderDetails.setSettleRealAmount(settleRealAmount1.subtract(newSettleRealAmount1));
        }
        if (FlymeUtils.isNotEmpty(orderDetails.getSettleRealAmount2())) {
            BigDecimal settleRealAmount2 = FlymeUtils.getBigDecimal(orderDetails.getSettleRealAmount2(), "0");
            BigDecimal newSettleRealAmount2 = FlymeUtils.getBigDecimal(newOrderDetails.getSettleRealAmount2(), "0");
            orderDetails.setSettleRealAmount2(settleRealAmount2.subtract(newSettleRealAmount2));
        }
        if (FlymeUtils.isNotEmpty(orderDetails.getSettleRealAmount3())) {
            BigDecimal settleRealAmount3 = FlymeUtils.getBigDecimal(orderDetails.getSettleRealAmount3(), "0");
            BigDecimal newSettleRealAmount3 = FlymeUtils.getBigDecimal(newOrderDetails.getSettleRealAmount3(), "0");
            orderDetails.setSettleRealAmount3(settleRealAmount3.subtract(newSettleRealAmount3));
        }
        saveOrUpdate(orderDetails);
        return orderDetails;
    }

    //拆出新明细
    private BusOrderDetails addOrderDetails(BusOrderDetails orderDetails, BusOrder busOrder, BigDecimal chaiFenNum, BigDecimal chiaFenAmont, BigDecimal ratio, BigDecimal ratio1) {

        BusOrderDetails newOrderDetails = new BusOrderDetails();
        BeanUtils.copyProperties(orderDetails, newOrderDetails);
        newOrderDetails.setOrderDetailsId(IdWorker.getId());
        newOrderDetails.setOrderDetailsState(CommonConstants.INT_1);
        //更新老明细
        newOrderDetails.setRadio(ratio);
        newOrderDetails.setSaleNum(chaiFenNum);
        OrderDetailsVo orderDetailsVo = new OrderDetailsVo();

        //计算金额
        initOrderDetailsVo(newOrderDetails, busOrder, orderDetailsVo);
        calculateCustomBondByHeSuan(newOrderDetails, busOrder, ratio);
        newOrderDetails.setSettleAmount2(getAmount(orderDetails.getSettleAmount2(), ratio1));
        newOrderDetails.setSettleAmount3(getAmount(orderDetails.getSettleAmount3(), ratio1));
        newOrderDetails.setSupplierRealAmount(getAmount(orderDetails.getSupplierRealAmount(), ratio1));
        newOrderDetails.setReturnSupplierBond(getAmount(orderDetails.getReturnSupplierBond(), ratio1));
        newOrderDetails.setLdSupplierRealAmount(getAmount(orderDetails.getLdSupplierRealAmount(), ratio1));
        BusDrugs drugs = drugsService.getById(orderDetails.getDrugsId());

        newOrderDetails.setSupplierBondState(orderDetails.getSupplierBondState());
        newOrderDetails.setSupplierBond(getAmount(orderDetails.getSupplierBond(), ratio1));
        newOrderDetails.setSupplierPayBond(getAmount(orderDetails.getSupplierPayBond(), ratio1));
        newOrderDetails.setInvoiceAmount(getAmount(orderDetails.getInvoiceAmount(), ratio1));
        BigDecimal retrunAmount = orderDetails.getReturnAmount();
        if (FlymeUtils.isNotEmpty(orderDetails.getReturnId())) {
            newOrderDetails.setReturnAmount(chiaFenAmont);
        }
        if (FlymeUtils.isNotEmpty(orderDetails.getTbzjId())) {
            newOrderDetails.setReturnCustomBond(FlymeUtils.getBigDecimal(newOrderDetails.getCustomBond(), "0").add(FlymeUtils.getBigDecimal(orderDetails.getCustomOverBond(), "0")));
        }
        newOrderDetails.setCreateTime(DateUtils.getNowDateTime());
        newOrderDetails.setUpdateTime(DateUtils.getNowDateTime());
        if (FlymeUtils.isNotEmpty(orderDetails.getSettleRealAmount())) {
            newOrderDetails.setSettleRealAmount(getAmount(orderDetails.getSettleRealAmount(), ratio1));
        }
        if (FlymeUtils.isNotEmpty(orderDetails.getSettleRealAmount2())) {
            newOrderDetails.setSettleRealAmount2(getAmount(orderDetails.getSettleRealAmount2(), ratio1));
        }
        if (FlymeUtils.isNotEmpty(orderDetails.getSettleRealAmount3())) {
            newOrderDetails.setSettleRealAmount3(getAmount(orderDetails.getSettleRealAmount3(), ratio1));
        }
        saveOrUpdate(newOrderDetails);
        return newOrderDetails;
    }


    //根据父明细拆出新明细
    private BusOrderDetails addOrderDetailsByParent(BusOrderDetails orderDetails, BusOrder busOrder, BigDecimal chaiFenNum, BigDecimal ratio) {

        BusOrderDetails newOrderDetails = new BusOrderDetails();
        BeanUtils.copyProperties(orderDetails, newOrderDetails);
        newOrderDetails.setOrderDetailsId(IdWorker.getId());
        newOrderDetails.setParentId(orderDetails.getOrderDetailsId());
        newOrderDetails.setOrderDetailsState(CommonConstants.INT_1);
        //更新老明细
        newOrderDetails.setRadio(ratio);
        newOrderDetails.setSaleNum(chaiFenNum);
        newOrderDetails.setSettleAmount2(getAmount(orderDetails.getSettleAmount2(), ratio));
        newOrderDetails.setSettleAmount3(getAmount(orderDetails.getSettleAmount3(), ratio));
        newOrderDetails.setInvoiceAmount(getAmount(orderDetails.getInvoiceAmount(), ratio));
        newOrderDetails.setSupplierRealAmount(getAmount(orderDetails.getSupplierRealAmount(), ratio));
        newOrderDetails.setLdSupplierRealAmount(getAmount(orderDetails.getLdSupplierRealAmount(), ratio));
        newOrderDetails.setSupplierPayBond(getAmount(orderDetails.getSupplierPayBond(), ratio));
        newOrderDetails.setCustomBond(getAmount(orderDetails.getCustomBond(), ratio));
        newOrderDetails.setReturnSupplierBond(getAmount(orderDetails.getReturnSupplierBond(), ratio));
        newOrderDetails.setCustomOverBond(getAmount(orderDetails.getCustomOverBond(), ratio));
        newOrderDetails.setCustomYsk(getAmount(orderDetails.getCustomYsk(), ratio));
        newOrderDetails.setReturnCustomBond(getAmount(orderDetails.getReturnCustomBond(), ratio));
        newOrderDetails.setReturnAmount(getAmount(orderDetails.getReturnAmount(), ratio));
        newOrderDetails.setCreateTime(DateUtils.getNowDateTime());
        newOrderDetails.setBudan("0");
        newOrderDetails.setUpdateTime(DateUtils.getNowDateTime());
        if (FlymeUtils.isNotEmpty(orderDetails.getSettleRealAmount())) {
            newOrderDetails.setSettleRealAmount(getAmount(orderDetails.getSettleRealAmount(), ratio));
        }
        if (FlymeUtils.isNotEmpty(orderDetails.getSettleRealAmount2())) {
            newOrderDetails.setSettleRealAmount2(getAmount(orderDetails.getSettleRealAmount2(), ratio));
        }
        if (FlymeUtils.isNotEmpty(orderDetails.getSettleRealAmount3())) {
            newOrderDetails.setSettleRealAmount3(getAmount(orderDetails.getSettleRealAmount3(), ratio));
        }
        OrderDetailsVo orderDetailsVo = new OrderDetailsVo();
        initOrderDetailsVo(newOrderDetails, busOrder, orderDetailsVo);
        saveOrUpdate(newOrderDetails);
        return newOrderDetails;
    }


    //根据父明细拆出新明细(计算剩余的)
    private BusOrderDetails addOrderDetailsByParent2(BusOrderDetails orderDetails, BusOrder busOrder, BusOrderDetails newOrderDetails, BigDecimal returnNum, BigDecimal ratio) {

        BusOrderDetails saveObj = new BusOrderDetails();
        BeanUtils.copyProperties(newOrderDetails, saveObj);
        saveObj.setOrderDetailsId(IdWorker.getId());
        saveObj.setParentId(orderDetails.getOrderDetailsId());
        saveObj.setOrderDetailsState(CommonConstants.INT_1);

        saveObj.setRadio(ratio);
        saveObj.setSaleNum(returnNum);


        BigDecimal invoicePaymentAmount = FlymeUtils.getBigDecimal(orderDetails.getInvoicePaymentAmount(), "0");
        BigDecimal invoicePaymentAmount1 = FlymeUtils.getBigDecimal(newOrderDetails.getInvoicePaymentAmount(), "0");
        saveObj.setInvoicePaymentAmount(invoicePaymentAmount.subtract(invoicePaymentAmount1));


        BigDecimal settleAmount = FlymeUtils.getBigDecimal(orderDetails.getSettleAmount(), "0");
        BigDecimal settleAmount1 = FlymeUtils.getBigDecimal(newOrderDetails.getSettleAmount(), "0");
        saveObj.setSettleAmount(settleAmount.subtract(settleAmount1));


        BigDecimal saleAmount = FlymeUtils.getBigDecimal(orderDetails.getSaleAmount(), "0");
        BigDecimal saleAmount1 = FlymeUtils.getBigDecimal(newOrderDetails.getSaleAmount(), "0");
        saveObj.setSaleAmount(saleAmount.subtract(saleAmount1));


        BigDecimal costAmount = FlymeUtils.getBigDecimal(orderDetails.getCostAmount(), "0");
        BigDecimal costAmount1 = FlymeUtils.getBigDecimal(newOrderDetails.getCostAmount(), "0");
        saveObj.setCostAmount(costAmount.subtract(costAmount1));

        BigDecimal settleSendAmount = FlymeUtils.getBigDecimal(orderDetails.getSettleSendAmount(), "0");
        BigDecimal settleSendAmount1 = FlymeUtils.getBigDecimal(newOrderDetails.getSettleSendAmount(), "0");
        saveObj.setSettleSendAmount(settleSendAmount.subtract(settleSendAmount1));


        BigDecimal customFloorAmount = FlymeUtils.getBigDecimal(orderDetails.getCustomFloorAmount(), "0");
        BigDecimal customFloorAmount1 = FlymeUtils.getBigDecimal(newOrderDetails.getCustomFloorAmount(), "0");
        saveObj.setCustomFloorAmount(customFloorAmount.subtract(customFloorAmount1));

        BigDecimal supplierGapUpAmount = FlymeUtils.getBigDecimal(orderDetails.getSupplierGapUpAmount(), "0");
        BigDecimal supplierGapUpAmount1 = FlymeUtils.getBigDecimal(newOrderDetails.getSupplierGapUpAmount(), "0");
        saveObj.setSupplierGapUpAmount(supplierGapUpAmount.subtract(supplierGapUpAmount1));

        BigDecimal supplierRetable = FlymeUtils.getBigDecimal(orderDetails.getSupplierRetable(), "0");
        BigDecimal supplierRetable1 = FlymeUtils.getBigDecimal(newOrderDetails.getSupplierRetable(), "0");
        saveObj.setSupplierRetable(supplierRetable.subtract(supplierRetable1));


        BigDecimal invoiceAmount = FlymeUtils.getBigDecimal(orderDetails.getInvoiceAmount(), "0");
        BigDecimal invoiceAmount1 = FlymeUtils.getBigDecimal(newOrderDetails.getInvoiceAmount(), "0");
        saveObj.setInvoiceAmount(invoiceAmount.subtract(invoiceAmount1));

        BigDecimal supplierRealAmount = FlymeUtils.getBigDecimal(orderDetails.getSupplierRealAmount(), "0");
        BigDecimal supplierRealAmount1 = FlymeUtils.getBigDecimal(newOrderDetails.getSupplierRealAmount(), "0");
        saveObj.setSupplierRealAmount(supplierRealAmount.subtract(supplierRealAmount1));


        BigDecimal ldSupplierRealAmount = FlymeUtils.getBigDecimal(orderDetails.getLdSupplierRealAmount(), "0");
        BigDecimal ldSupplierRealAmount1 = FlymeUtils.getBigDecimal(newOrderDetails.getLdSupplierRealAmount(), "0");
        saveObj.setLdSupplierRealAmount(ldSupplierRealAmount.subtract(ldSupplierRealAmount1));

        BigDecimal supplierBond = FlymeUtils.getBigDecimal(orderDetails.getSupplierBond(), "0");
        BigDecimal supplierBond1 = FlymeUtils.getBigDecimal(newOrderDetails.getSupplierBond(), "0");
        saveObj.setSupplierBond(supplierBond.subtract(supplierBond1));

        BigDecimal supplierPayBond = FlymeUtils.getBigDecimal(orderDetails.getSupplierPayBond(), "0");
        BigDecimal supplierPayBond1 = FlymeUtils.getBigDecimal(newOrderDetails.getSupplierPayBond(), "0");
        saveObj.setSupplierPayBond(supplierPayBond.subtract(supplierPayBond1));


        BigDecimal supplierGapUpTaxesAmount = FlymeUtils.getBigDecimal(orderDetails.getSupplierGapUpTaxesAmount(), "0");
        BigDecimal supplierGapUpTaxesAmount1 = FlymeUtils.getBigDecimal(newOrderDetails.getSupplierGapUpTaxesAmount(), "0");
        saveObj.setSupplierGapUpTaxesAmount(supplierGapUpTaxesAmount.subtract(supplierGapUpTaxesAmount1));

        BigDecimal customGapUpAmount = FlymeUtils.getBigDecimal(orderDetails.getCustomGapUpAmount(), "0");
        BigDecimal customGapUpAmount1 = FlymeUtils.getBigDecimal(newOrderDetails.getCustomGapUpAmount(), "0");
        saveObj.setCustomGapUpAmount(customGapUpAmount.subtract(customGapUpAmount1));

        BigDecimal customGapUpTaxesAmount = FlymeUtils.getBigDecimal(orderDetails.getCustomGapUpTaxesAmount(), "0");
        BigDecimal customGapUpTaxesAmount1 = FlymeUtils.getBigDecimal(newOrderDetails.getCustomGapUpTaxesAmount(), "0");
        saveObj.setCustomGapUpTaxesAmount(customGapUpTaxesAmount.subtract(customGapUpTaxesAmount1));


        BigDecimal customSettleGapUpAmount = FlymeUtils.getBigDecimal(orderDetails.getCustomSettleGapUpAmount(), "0");
        BigDecimal customSettleGapUpAmount1 = FlymeUtils.getBigDecimal(newOrderDetails.getCustomSettleGapUpAmount(), "0");
        saveObj.setCustomSettleGapUpAmount(customSettleGapUpAmount.subtract(customSettleGapUpAmount1));


        BigDecimal profitAmount = FlymeUtils.getBigDecimal(orderDetails.getProfitAmount(), "0");
        BigDecimal profitAmount1 = FlymeUtils.getBigDecimal(newOrderDetails.getProfitAmount(), "0");
        saveObj.setProfitAmount(profitAmount.subtract(profitAmount1));


        BigDecimal customBond = FlymeUtils.getBigDecimal(orderDetails.getCustomBond(), "0");
        BigDecimal customBond1 = FlymeUtils.getBigDecimal(newOrderDetails.getCustomBond(), "0");
        saveObj.setCustomBond(customBond.subtract(customBond1));

        BigDecimal customOverBond = FlymeUtils.getBigDecimal(orderDetails.getCustomOverBond(), "0");
        BigDecimal customOverBond1 = FlymeUtils.getBigDecimal(newOrderDetails.getCustomOverBond(), "0");
        saveObj.setCustomOverBond(customOverBond.subtract(customOverBond1));

        BigDecimal customYsk = FlymeUtils.getBigDecimal(orderDetails.getCustomYsk(), "0");
        BigDecimal customYsk1 = FlymeUtils.getBigDecimal(newOrderDetails.getCustomYsk(), "0");
        saveObj.setCustomYsk(customYsk.subtract(customYsk1));

        BigDecimal returnAmount = FlymeUtils.getBigDecimal(orderDetails.getReturnAmount(), "0");
        BigDecimal returnAmount1 = FlymeUtils.getBigDecimal(newOrderDetails.getReturnAmount(), "0");
        saveObj.setReturnAmount(returnAmount.subtract(returnAmount1));

        BigDecimal returnCustomBond = FlymeUtils.getBigDecimal(orderDetails.getReturnCustomBond(), "0");
        BigDecimal returnCustomBond1 = FlymeUtils.getBigDecimal(newOrderDetails.getReturnCustomBond(), "0");
        saveObj.setReturnCustomBond(returnCustomBond.subtract(returnCustomBond1));

        BigDecimal returnSupplierBond = FlymeUtils.getBigDecimal(orderDetails.getReturnSupplierBond(), "0");
        BigDecimal returnSupplierBond1 = FlymeUtils.getBigDecimal(newOrderDetails.getReturnSupplierBond(), "0");
        saveObj.setReturnSupplierBond(returnSupplierBond.subtract(returnSupplierBond1));

        if (FlymeUtils.isNotEmpty(orderDetails.getSettleRealAmount())) {
            BigDecimal settleRealAmount1 = FlymeUtils.getBigDecimal(orderDetails.getSettleRealAmount(), "0");
            BigDecimal newSettleRealAmount1 = FlymeUtils.getBigDecimal(newOrderDetails.getSettleRealAmount(), "0");
            saveObj.setSettleRealAmount(settleRealAmount1.subtract(newSettleRealAmount1));
        }
        if (FlymeUtils.isNotEmpty(orderDetails.getSettleRealAmount2())) {
            BigDecimal settleRealAmount2 = FlymeUtils.getBigDecimal(orderDetails.getSettleRealAmount2(), "0");
            BigDecimal newSettleRealAmount2 = FlymeUtils.getBigDecimal(newOrderDetails.getSettleRealAmount2(), "0");
            saveObj.setSettleRealAmount2(settleRealAmount2.subtract(newSettleRealAmount2));
        }
        if (FlymeUtils.isNotEmpty(orderDetails.getSettleRealAmount3())) {
            BigDecimal settleRealAmount3 = FlymeUtils.getBigDecimal(orderDetails.getSettleRealAmount3(), "0");
            BigDecimal newSettleRealAmount3 = FlymeUtils.getBigDecimal(newOrderDetails.getSettleRealAmount3(), "0");
            saveObj.setSettleRealAmount3(settleRealAmount3.subtract(newSettleRealAmount3));
        }

        saveOrUpdate(saveObj);
        return saveObj;
    }


    private BusOrderDetails addTuiHuoOrderDetails(BusOrderDetails orderDetails, BigDecimal returnNum, String saleDate) {
        BigDecimal ratio = new BigDecimal("-1");
        BusOrderDetails newOrderDetails = new BusOrderDetails();
        newOrderDetails.setSaleNum(returnNum);
        newOrderDetails.setParentId(orderDetails.getOrderDetailsId());
        newOrderDetails.setOrderId(orderDetails.getOrderId());
        newOrderDetails.setCompanyId(orderDetails.getCompanyId());
        newOrderDetails.setOrganizationId(orderDetails.getOrganizationId());
        newOrderDetails.setDeptId(orderDetails.getDeptId());
        newOrderDetails.setSaleManId(orderDetails.getSaleManId());
        newOrderDetails.setCustomId(orderDetails.getCustomId());
        newOrderDetails.setSupplierId(orderDetails.getSupplierId());
        newOrderDetails.setDrugsId(orderDetails.getDrugsId());
        newOrderDetails.setDrugsLotId(orderDetails.getDrugsLotId());
        newOrderDetails.setSaleType(SaleTypeEnum.Th.getCode().toString());
        newOrderDetails.setSaleDate(DateUtils.parseDate(saleDate));
        newOrderDetails.setSalePrice(orderDetails.getSalePrice());

        newOrderDetails.setSettlePrice(orderDetails.getSettlePrice());
        newOrderDetails.setSettleAmount(getAmount(orderDetails.getSettleAmount(), ratio));
        newOrderDetails.setSettleAmount2(getAmount(orderDetails.getSettleAmount2(), ratio));
        newOrderDetails.setSettleAmount3(getAmount(orderDetails.getSettleAmount3(), ratio));
        newOrderDetails.setInvoiceAmount(getAmount(orderDetails.getInvoiceAmount(), ratio));
        newOrderDetails.setCostPrice(orderDetails.getCostPrice());
        newOrderDetails.setSaleAmount(getAmount(orderDetails.getSaleAmount(), ratio));
        newOrderDetails.setCostAmount(getAmount(orderDetails.getCostAmount(), ratio));
        newOrderDetails.setSettleSendAmount(getAmount(orderDetails.getSettleSendAmount(), ratio));
        newOrderDetails.setCustomFloorAmount(getAmount(orderDetails.getCustomFloorAmount(), ratio));
        newOrderDetails.setSupplierGapUpAmount(getAmount(orderDetails.getSupplierGapUpAmount(), ratio));
        newOrderDetails.setSupplierRetable(getAmount(orderDetails.getSupplierRetable(), ratio));
        newOrderDetails.setSupplierGapUpTaxesAmount(getAmount(orderDetails.getSupplierGapUpTaxesAmount(), ratio));
        newOrderDetails.setCustomGapUpAmount(getAmount(orderDetails.getCustomGapUpAmount(), ratio));
        newOrderDetails.setCustomGapUpTaxesAmount(getAmount(orderDetails.getCustomGapUpTaxesAmount(), ratio));
        newOrderDetails.setCustomSettleGapUpAmount(getAmount(orderDetails.getCustomSettleGapUpAmount(), ratio));
        newOrderDetails.setDiscountPrice(orderDetails.getDiscountPrice());
        newOrderDetails.setSupplierRateId(orderDetails.getSupplierRateId());
        newOrderDetails.setBudan("0");
        newOrderDetails.setCustomRateId(orderDetails.getCustomRateId());
        newOrderDetails.setSupplierTaxRate(orderDetails.getSupplierTaxRate());
        newOrderDetails.setSupplierSettleRate(orderDetails.getSupplierSettleRate());
        newOrderDetails.setRefundFormulaId(orderDetails.getRefundFormulaId());
        newOrderDetails.setRefundFormulaContent(orderDetails.getRefundFormulaContent());
        newOrderDetails.setHighTaxRateFormulaId(orderDetails.getHighTaxRateFormulaId());
        newOrderDetails.setHighTaxRateFormulaContent(orderDetails.getHighTaxRateFormulaContent());
        newOrderDetails.setCustomTaxRate(orderDetails.getCustomTaxRate());
        newOrderDetails.setCustomSettleGapUpTaxRate(orderDetails.getCustomSettleGapUpTaxRate());
        newOrderDetails.setCustomSettleRate(orderDetails.getCustomSettleRate());
        newOrderDetails.setSettleFormulaId(orderDetails.getSettleFormulaId());
        newOrderDetails.setSettleFormulaContent(orderDetails.getSettleFormulaContent());
        newOrderDetails.setProfitAmountFormulaId(orderDetails.getProfitAmountFormulaId());
        newOrderDetails.setProfitAmountFormulaContent(orderDetails.getProfitAmountFormulaContent());
        newOrderDetails.setProfitAmount(getAmount(orderDetails.getProfitAmount(), ratio));
        newOrderDetails.setOrderDetailsState(CommonConstants.ENABLED);
        newOrderDetails.setRadio(orderDetails.getRadio().multiply(ratio));
        newOrderDetails.setSupplierBondState(orderDetails.getSupplierBondState());
        newOrderDetails.setSupplierRefundState(orderDetails.getSupplierRefundState());
        newOrderDetails.setCustomReturnState("0");
        newOrderDetails.setCustomBondState(orderDetails.getCustomBondState());
        newOrderDetails.setCustomYsk(getAmount(orderDetails.getCustomYsk(), ratio));
        //newOrderDetails.setInvoicePaymentAmount(getAmount(orderDetails.getInvoicePaymentAmount(), ratio));
        newOrderDetails.setInvoicePaymentAmount(new BigDecimal("0"));
        newOrderDetails.setReturnCustomBond(new BigDecimal("0"));
        newOrderDetails.setCustomBond(new BigDecimal("0"));
        newOrderDetails.setCustomOverBond(new BigDecimal("0"));
        newOrderDetails.setSupplierBond(new BigDecimal("0"));
        newOrderDetails.setSupplierPayBond(new BigDecimal("0"));
        newOrderDetails.setReturnSupplierBond(new BigDecimal("0"));
        newOrderDetails.setSettleRealAmount(new BigDecimal("0"));
        newOrderDetails.setSettleRealAmount3(new BigDecimal("0"));
        newOrderDetails.setSupplierRealAmount(new BigDecimal("0"));
        newOrderDetails.setSettleRealAmount2(new BigDecimal("0"));
        newOrderDetails.setDianfuId(orderDetails.getDianfuId());
        newOrderDetails.setReturnAmount(new BigDecimal("0"));
        newOrderDetails.setSettleState("0");
        newOrderDetails.setSettleState2("0");
        newOrderDetails.setSettleState3("0");
        saveOrUpdate(newOrderDetails);
        return newOrderDetails;
    }


    private BigDecimal getAmount(BigDecimal amount, BigDecimal radio) {
        if (FlymeUtils.isNotEmpty(amount)) {
            return amount.multiply(radio).setScale(2, BigDecimal.ROUND_HALF_UP);
        }
        return new BigDecimal("0");
    }

    @Override
    public ResultBody deleteTuibu(Long orderDetailsId) {
        BusOrderDetails busOrderDetails = orderDetailsService.getById(orderDetailsId);
        Long parentId = busOrderDetails.getOrderId();
        if (FlymeUtils.isNotEmpty(parentId)) {
            orderService.removeById(parentId);
        }
        removeById(orderDetailsId);
        return ResultBody.ok();
    }

    @Override
    public ResultBody updateLotNo(Long drugsLotId, Long orderDetailsId) {
        CriteriaUpdate cu = new CriteriaUpdate();
        cu.set(true, "drugsLotId", drugsLotId);
        cu.eq(true, "orderDetailsId", orderDetailsId);
        Boolean tag = update(cu);
        return ResultBody.msg("更新成功");
    }

    @Override
    public ResultBody revoke(Long returnId) {
        CriteriaUpdate cu = new CriteriaUpdate();
        cu.set(true, "customReturnState", 0);
        cu.set(true, "returnDate", "");
        cu.set(true, "returnAmount", 0);
        cu.eq(true, "returnId", returnId);
        Boolean tag = update(cu);
        paymentService.updatePaymentState(returnId, CommonConstants.INT_0);
        return ResultBody.ok("回款撤销成功");
    }

    @Override
    public ResultBody updateRenkuan(String renkuanDate, String supplierRetDate2, Long orderDetailsId) {
        CriteriaUpdate cu = new CriteriaUpdate();
        if (FlymeUtils.isNotEmpty(supplierRetDate2)) {
            cu.set("supplierRetDate2", supplierRetDate2);
        }
        if (FlymeUtils.isNotEmpty(renkuanDate)) {
            cu.set("renkuanDate", renkuanDate);
        }
        cu.eq(true, "orderDetailsId", orderDetailsId);
        Boolean tag = update(cu);
        return ResultBody.msg("更新成功");
    }

    @Override
    public ResultBody updateHuikuan(String returnDate, BigDecimal returnAmount, Long orderDetailsId) {
        CriteriaUpdate cu = new CriteriaUpdate();
        cu.set("returnDate", returnDate);
        cu.set("returnAmount", returnAmount);
        cu.eq(true, "orderDetailsId", orderDetailsId);
        Boolean tag = update(cu);
        return ResultBody.msg("更新成功");
    }


    @Override
    public void updateCustomBondState(Long orderId, Integer state) {
        CriteriaUpdate cu = new CriteriaUpdate();
        cu.set(true, "customBondState", state);
        cu.set(true, "renkuanDate", DateUtils.getYear() + "-" + DateUtils.getMonth());
        cu.eq(true, "orderId", orderId);
        update(cu);
    }

    @Override
    public void updateReturnCustomBond(Long orderDetailsId, BigDecimal returnCustomBond, String returnDate) {
        CriteriaUpdate cu = new CriteriaUpdate();
        cu.set(true, "customBondState", CommonConstants.INT_2);
        cu.set(true, "returnCustomBond", returnCustomBond);
        cu.set(true, "customBondRetDate", returnDate);
        cu.eq(true, "orderDetailsId", orderDetailsId);
        update(cu);
    }


    @Override
    public void updateSupplierBondState(BusPayment payment, Long orderId, Integer state) {
        CriteriaUpdate cu = new CriteriaUpdate();
        if (FlymeUtils.isNotEmpty(payment)) {
            cu.set(true, "supplierPayBond", payment.getAmount());
            cu.set(true, "supplierBondPayDate", DateUtils.formatDate(payment.getPayDate(), "yyyy-MM-dd"));
            cu.set(true, "dianfuId", payment.getPaymentId());
        }
        cu.set(true, "supplierBondState", state);
        cu.eq(true, "orderId", orderId);
        update(cu);
    }

    @Override
    public void updateReturnDianfuAmount(BusPayment payment) {
        CriteriaUpdate cu = new CriteriaUpdate();
        cu.setSql("returnSupplierBond=supplierPayBond");
        cu.set(true, "supplierRetBondDate", DateUtils.formatDate(payment.getPayDate(), "yyyy-MM-dd"));
        cu.set(true, "supplierBondState", CommonConstants.INT_3);
        cu.eq(true, "returnDianfuId", payment.getPaymentId());
        update(cu);
    }

    @Override
    public void updateReturnDianfuId(BusPayment payment, String selectIds) {
        CriteriaUpdate cu = new CriteriaUpdate();
        cu.set(true, "returnDianfuId", payment.getPaymentId());
        cu.in(true, "orderDetailsId", selectIds.split(","));
        update(cu);
    }


    @Override
    public void clearSupplierBondState(Long orderId, Integer state) {
        CriteriaUpdate cu = new CriteriaUpdate();
        cu.set(true, "supplierPayBond", 0);
        cu.set(true, "dianfuId", null);
        cu.set(true, "supplierBondPayDate", null);
        cu.set(true, "supplierBondState", state);
        cu.eq(true, "orderId", orderId);
        update(cu);
    }

    @Override
    public void clearReturnDianfuId(Serializable returnDianfuId) {
        CriteriaUpdate cu = new CriteriaUpdate();
        cu.set(true, "returnSupplierBond", 0);
        cu.set(true, "supplierRetBondDate", null);
        cu.set(true, "returnDianfuId", null);
        cu.set(true, "supplierBondState", 2);
        cu.eq(true, "returnDianfuId", returnDianfuId);
        update(cu);
    }


    @Override
    public List<BusOrderDetails> selectByKaiPiaoId(Long kaipiaoId) {
        CriteriaQuery cq = new CriteriaQuery(BusOrderDetails.class);
        cq.eq(true, "kaipiaoId", kaipiaoId);
        cq.eq(true, "orderDetailsState", CommonConstants.ENABLED);
        return list(cq);
    }

    @Override
    public List<BusOrderDetails> selectByTbzjId(Long tbzjId) {
        CriteriaQuery cq = new CriteriaQuery(BusOrderDetails.class);
        cq.eq(true, "tbzjId", tbzjId);
        cq.eq(true, "orderDetailsState", CommonConstants.ENABLED);
        return list(cq);
    }


    @Override
    public BusOrderDetails selectPiaozhe(Long orderId) {
        CriteriaQuery cq = new CriteriaQuery(BusOrderDetails.class);
        cq.eq(true, "orderId", orderId);
        cq.eq(true, "orderDetailsState", CommonConstants.ENABLED);
        cq.eq(true, "saleType", SaleTypeEnum.Pz.getCode());
        return getOne(cq, false);
    }

    @Override
    public List<BusOrderDetails> selectBuhuo(Long orderDetailsId) {
        CriteriaQuery cq = new CriteriaQuery(BusOrderDetails.class);
        cq.eq(true, "parentId", orderDetailsId);
        cq.eq(true, "saleType", SaleTypeEnum.Bh.getCode());
        return list(cq);
    }

    @Override
    public Boolean updateOrderDetailsState(Long orderId, BusOrderDetails orderDetails, Integer orderDetailsState) {
        CriteriaUpdate cu = new CriteriaUpdate();
        cu.set(true, "orderDetailsState", orderDetailsState);
        cu.eq(true, "orderId", orderId);
        cu.eq(true, "orderDetailsId", orderDetails.getOrderDetailsId());
        cu.isNull("parentId");
        return update(cu);
    }


    @Override
    public BigDecimal totalCustomBond(Long orderId) {
        CriteriaQuery<BusOrderDetails> cq = new CriteriaQuery(BusOrderDetails.class);
        cq.select("sum(customBond)");
        cq.eq("orderDetailsState", CommonConstants.ENABLED);
        cq.eq(true, "orderId", orderId);
        BigDecimal amount = getObj(cq, e -> new BigDecimal(e.toString()));
        return FlymeUtils.getBigDecimal(amount, new BigDecimal("0"));
    }

    @Override
    public BigDecimal countByDrugLotId(Long drugsLotId) {
        CriteriaQuery<BusOrderDetails> cq = new CriteriaQuery(BusOrderDetails.class);
        cq.select("sum(saleNum)");
        cq.eq("orderDetailsState", CommonConstants.ENABLED);
        cq.eq(true, "drugsLotId", drugsLotId);
        return getObj(cq, e -> new BigDecimal(e.toString()));
    }

    @Override
    public Integer countByOrderDetails(String orderDetailsId) {
        CriteriaQuery<BusOrderDetails> cq = new CriteriaQuery(BusOrderDetails.class);
        cq.select("count(DISTINCT orderId)");
        cq.in(true, "orderDetailsId", orderDetailsId.split(","));
        return getObj(cq, e -> Integer.parseInt(e.toString()));
    }


    @Override
    public BigDecimal totalSaleNum(Long orderId) {
        CriteriaQuery<BusOrderDetails> cq = new CriteriaQuery(BusOrderDetails.class);
        cq.select("sum(saleNum)");
        cq.eq("orderDetailsState", CommonConstants.ENABLED);
        cq.eq(true, "orderId", orderId);
        BigDecimal amount = getObj(cq, e -> new BigDecimal(e.toString()));
        return FlymeUtils.getBigDecimal(amount, new BigDecimal("0"));
    }

    @Override
    public List<EntityMap> selectOrderInfoDetails(Map params) {
        CriteriaQuery<BusOrderDetails> cq = new CriteriaQuery(params, BusOrderDetails.class);
        Long orderId = cq.getLong("orderId");
        BusOrder order = orderService.getById(orderId);
        if (FlymeUtils.isNotEmpty(order)) {
            Integer orderType = order.getOrderType();
            cq.select(BusOrderDetails.class, "*");
            cq.addSelect(BusOrder.class, "supplierBondType", "customBondType", "orderState", "invoiceSendType", "sendNo", "invoiceAttachment", "sendAttachment", "customFpId");
            cq.addSelect(BusSupplier.class, "supplierName");
            cq.addSelect(BusCustom.class, "customName");
            cq.addSelect(BusDrugs.class, "drugsName", "drugsSpec");
            cq.addSelect(BusDrugslot.class, "drugsLotNo");
            List<Long> orderIds = orderService.selectOrderId(orderId);
            if (orderType.equals(SaleTypeEnum.Th.getCode())) {
                orderIds.add(order.getParentId());
            }
            if (FlymeUtils.isNotEmpty(orderIds)) {
                cq.in("ord.orderId", orderIds);
            }
            cq.eq(BusOrderDetails.class, "orderDetailsState", CommonConstants.ENABLED);
            cq.createJoin(BusSupplier.class);
            cq.createJoin(BusDrugs.class);
            cq.createJoin(BusCustom.class);
            cq.createJoin(BusOrder.class);
            cq.createJoin(BusDrugslot.class);
            List<EntityMap> list = selectEntityMap(cq);
            for (EntityMap map : list) {
                Long orderDetailsId = map.getLong("orderDetailsId");
                Long orderId2 = map.getLong("orderId");
                Integer customBondType = map.getInt("customBondType");
                if (customBondType.equals(1) || customBondType.equals(3) || customBondType.equals(2) || customBondType.equals(6)) {
                    BigDecimal orderCustomBond = map.getBigDecimal("customBond");
                    if (FlymeUtils.isNotEmpty(orderCustomBond)) {
                        map.put("customBond", orderCustomBond);
                    } else {
                        map.put("customBond", "-");
                    }
                }

                //预付款情况计算未回款金额
                if (customBondType.equals(7)) {
                    BusOrder busOrder = orderService.getById(orderId);
                    BigDecimal saleAmount = map.getBigDecimal("saleAmount");
                    BigDecimal returnAmount = map.getBigDecimal("returnAmount");
                    BigDecimal customYsk = map.getBigDecimal("customYsk");
                    if (FlymeUtils.isNotEmpty(customYsk)) {
                        map.put("customYsk", customYsk);
                        //计算未回款金额
                        map.put("noReturnAmount", saleAmount.subtract(returnAmount).subtract(customYsk));
                    } else {
                        map.put("returnAmount", "-");
                    }
                }
                BigDecimal saleAmount = map.getBigDecimal("saleAmount");
                if (customBondType.equals(0) && FlymeUtils.gtzero(saleAmount)) {
                    map.put("returnAmount", saleAmount);
                    order = orderService.getById(orderId2);
                    if (FlymeUtils.isNotEmpty(order.getTakeDate())) {
                        map.put("returnDate", DateUtils.formatDate(order.getTakeDate()));
                    }
                }
            }

            return list;
        } else {
            return null;
        }
    }

    @Override
    public Boolean updateCbReturn(BusPayment payment, Long orderDetailsId) {
        BusOrderDetails orderDetails = new BusOrderDetails();
        CriteriaUpdate cu = new CriteriaUpdate();
        cu.set(true, "tbzjId", payment.getPaymentId());
        cu.eq(true, "orderDetailsId", orderDetailsId);
        return update(cu);
    }

    @Override
    public Boolean updateHuiKuan(BusPayment payment, Long orderDetailsId) {
        BusOrderDetails orderDetails = new BusOrderDetails();
        CriteriaUpdate cu = new CriteriaUpdate();
        cu.set(true, "returnId", payment.getPaymentId());
        cu.set(true, "returnAmount", payment.getAmount());
        cu.set(true, "returnDate", DateUtils.formatDate(payment.getAmountDate(), "yyyy-MM-dd"));
        cu.eq(true, "orderDetailsId", orderDetailsId);
        return update(cu);
    }

    /**
     * 更新开票信息
     */
    @Override
    public Boolean updateInvoiceInfo(BusPayment payment) {
        if (FlymeUtils.allNotNull(payment)) {
            Integer settleType = FlymeUtils.getInteger(payment.getSettleType(), 1);
            if (settleType.equals(1)) {
                CriteriaUpdate cu = new CriteriaUpdate();
                BusInvoiceunit invoiceunit = invoiceunitService.getById(payment.getInvoiceUnitId());
                if (FlymeUtils.isNotEmpty(invoiceunit)) {
                    cu.set(true, "invoiceunitName", invoiceunit.getInvoiceunitName());
                    cu.set(true, "invoiceunitId", invoiceunit.getInvoiceUnitId());
                }
                cu.set(true, "invoicePaymentAmount", payment.getInvoiceAmount());
                cu.set(true, "invoiceAmountDate", DateUtils.formatDate(payment.getAmountDate(), "yyyy-MM-dd"));
                cu.set(true, "invoicePaymentNo", payment.getPaymentNo());
                cu.set(true, "invoiceSj", payment.getAmount());
                cu.set(true, "supplierRefundState", CommonConstants.INT_1);
                cu.eq(true, "kaipiaoId", payment.getPaymentId());
                update(cu);
            }
        }
        return true;
    }

    /**
     * 更新开票信息
     */
    @Override
    public Boolean updateKaipiaoId(BusPayment payment, String orderDetailsIds) {
        if (FlymeUtils.allNotNull(payment, orderDetailsIds)) {
            Integer paymentState = payment.getPaymentState();
            CriteriaUpdate cu = new CriteriaUpdate();
            Object[] list = orderDetailsIds.split(",");
            cu.set(true, "kaipiaoId", payment.getPaymentId());
            cu.in("orderDetailsId", list);
            update(cu);
        }
        return true;
    }

    /**
     * 更新开票信息
     */
    @Override
    public Boolean updateKaipiaoId2(BusPayment payment, String orderDetailsIds) {
        if (FlymeUtils.allNotNull(payment, orderDetailsIds)) {
            Integer paymentState = payment.getPaymentState();
            CriteriaUpdate cu = new CriteriaUpdate();
            Object[] list = orderDetailsIds.split(",");
            cu.set(true, "kaipiaoId2", payment.getPaymentId());
            cu.in("orderDetailsId", list);
            update(cu);
        }
        return true;
    }

    /**
     * 清空开票信息
     */
    @Override
    public Boolean clearInvoiceInfo(Serializable kaipiaoId, Integer settleType) {
        if (FlymeUtils.allNotNull(kaipiaoId)) {

            CriteriaUpdate cu = new CriteriaUpdate();
            if (settleType.equals(1)) {
                cu.set(true, "kaipiaoId", null);
                cu.eq(true, "kaipiaoId", kaipiaoId);
            } else {
                cu.set(true, "kaipiaoId2", null);
                cu.eq(true, "kaipiaoId2", kaipiaoId);
            }
            update(cu);
        }
        return true;
    }


    /**
     * 更新返款信息
     */
    @Override
    public Boolean updateFankuanInfo(BusPayment payment, Long kaipiaoId) {
        if (FlymeUtils.allNotNull(payment, kaipiaoId)) {
            Integer paymentState = payment.getPaymentState();
            Integer settleType = FlymeUtils.getInteger(payment.getSettleType(), 1);
            CriteriaUpdate cu = new CriteriaUpdate();
            if (settleType.equals(1)) {
                cu.setSql("supplierRealAmount=supplierRetable");
                cu.set(true, "supplierRetDate", DateUtils.formatDate(payment.getPayDate(), "yyyy-MM-dd"));
                cu.set(true, "supplierRetDate2", DateUtils.formatDate(payment.getPayDate(), "yyyy-MM"));
                cu.set(true, "supplierRefundState", CommonConstants.INT_2);
                cu.eq("fankuanId", payment.getPaymentId().toString());
            } else {
                cu.setSql("ldSupplierRealAmount=supplierRetable2");
                cu.set(true, "ldSupplierRetDate", DateUtils.formatDate(payment.getPayDate(), "yyyy-MM-dd"));
                cu.set(true, "supplierRetDate2", DateUtils.formatDate(payment.getPayDate(), "yyyy-MM"));
                cu.set(true, "supplierRefundState2", CommonConstants.INT_2);
                cu.eq("fankuanId2", payment.getPaymentId().toString());
            }
            update(cu);
        }
        return true;
    }

    /**
     * 关联返款ID
     */
    @Override
    public Boolean updateFankuanId(BusPayment payment, Long kaipiaoId) {
        if (FlymeUtils.allNotNull(payment, kaipiaoId)) {
            Integer settleType = FlymeUtils.getInteger(payment.getSettleType(), 1);
            Integer paymentState = payment.getPaymentState();
            CriteriaUpdate cu = new CriteriaUpdate();
            if (settleType.equals(1)) {
                cu.set(true, "fankuanId", payment.getPaymentId());
                cu.eq("kaipiaoId", kaipiaoId.toString());
            } else {
                cu.set(true, "fankuanId2", payment.getPaymentId());
                cu.eq("kaipiaoId2", kaipiaoId.toString());
            }
            update(cu);
        }
        return true;
    }

    @Override
    public Boolean updateJiesuanInfo(BusPayment payment, BigDecimal yesSettleAmount, Integer settleType) {
        if (FlymeUtils.allNotNull(payment)) {
            Integer paymentState = payment.getPaymentState();
            Long panyBankId = payment.getPayBankId();
            CriteriaUpdate cu = new CriteriaUpdate();
            SysBank bank = bankService.getById(panyBankId);
            cu.set("settlePayBankName", bank.getBankName());
            //状态=2时说明是已结算
            if (settleType.equals(1)) {
                cu.setSql("settleRealAmount=settleAmount");
                cu.set(true, "settlePayDate", DateUtils.formatDate(payment.getPayDate(), "yyyy-MM-dd"));
                cu.set(true, "settleState", CommonConstants.INT_2);
                cu.eq(true, "jiesuanId", payment.getPaymentId());
            }
            if (settleType.equals(2)) {
                cu.setSql("settleRealAmount2=settleAmount2");
                cu.set(true, "settlePayDate2", DateUtils.formatDate(payment.getPayDate(), "yyyy-MM-dd"));
                cu.set(true, "settleState2", CommonConstants.INT_2);
                cu.eq(true, "jiesuanId2", payment.getPaymentId());
            }
            if (settleType.equals(3)) {
                cu.setSql("settleRealAmount3=settleAmount3");
                cu.set(true, "settlePayDate3", DateUtils.formatDate(payment.getPayDate(), "yyyy-MM-dd"));
                cu.set(true, "settleState3", CommonConstants.INT_2);
                cu.eq(true, "jiesuanId3", payment.getPaymentId());
            }
            update(cu);
        }
        return true;
    }


    @Override
    public Boolean updateJiesuanId(BusPayment payment, String selectIds, Integer settleType) {
        if (FlymeUtils.allNotNull(payment, selectIds)) {
            Integer paymentState = payment.getPaymentState();
            Long panyBankId = payment.getPayBankId();
            CriteriaUpdate cu = new CriteriaUpdate();
            SysBank bank = bankService.getById(panyBankId);
            if (settleType.equals(1)) {
                cu.set(true, "jiesuanId", payment.getPaymentId());
            }
            if (settleType.equals(2)) {
                cu.set(true, "jiesuanId2", payment.getPaymentId());
            }
            if (settleType.equals(3)) {
                cu.set(true, "jiesuanId3", payment.getPaymentId());
            }
            cu.in("orderDetailsId", selectIds.split(","));
            update(cu);
        }
        return true;
    }


    @Override
    public Boolean clearJiesuanInfo(Serializable jiesuanId, Integer settleType) {
        CriteriaUpdate cu = new CriteriaUpdate();
        if (settleType.equals(1)) {
            cu.setSql("jiesuanId=null");
        }
        if (settleType.equals(2)) {
            cu.setSql("jiesuanId2=null");
        }
        if (settleType.equals(3)) {
            cu.setSql("jiesuanId3=null");
        }
        cu.eq("jiesuanId", jiesuanId.toString());
        return update(cu);
    }


    /**
     * 清空返款信息
     */
    @Override
    public Boolean clearFankuanInfo(Serializable fankuanId) {
        if (FlymeUtils.allNotNull(fankuanId)) {
            BusPayment payment = paymentService.getById(fankuanId);
            Integer settleType = FlymeUtils.getInteger(payment.getSettleType(), 1);
            CriteriaUpdate cu = new CriteriaUpdate();
            if (settleType.equals(1)) {
                cu.set(true, "fankuanId", null);
                cu.eq(true, "fankuanId", fankuanId.toString());
            } else {
                cu.set(true, "fankuanId2", null);
                cu.eq(true, "fankuanId2", fankuanId.toString());
            }
            update(cu);
        }
        return true;
    }

    /**
     * 清空回款信息
     */
    @Override
    public Boolean clearHuiKuanInfo(Serializable returnId) {
        if (FlymeUtils.allNotNull(returnId)) {
            CriteriaUpdate cu = new CriteriaUpdate();
            cu.set(true, "returnId", null);
            cu.set(true, "returnAmount", new BigDecimal("0"));
            cu.set(true, "returnDate", null);
            cu.set(true, "renkuanDate", null);
            cu.set(true, "returnBank", null);
            cu.eq(true, "returnId", returnId.toString());
            update(cu);
        }
        return true;
    }

    /**
     * 清空回款信息
     */
    @Override
    public Boolean clearTbzj(Serializable tbzjId) {
        if (FlymeUtils.allNotNull(tbzjId)) {
            CriteriaUpdate cu = new CriteriaUpdate();
            cu.set(true, "tbzjId", null);
            cu.set(true, "returnCustomBond", new BigDecimal("0"));
            cu.set(true, "customBondRetDate", null);
            cu.eq(true, "tbzjId", tbzjId.toString());
            update(cu);
        }
        return true;
    }

    @Override
    public Boolean updateHuikuanInfo(BusPayment payment) {
        BusOrderDetails orderDetails = new BusOrderDetails();
        CriteriaUpdate cu = new CriteriaUpdate();
        cu.set(true, "returnAmount", payment.getAmount());
        cu.set(true, "returnDate", DateUtils.formatDate(payment.getAmountDate(), "yyyy-MM-dd"));
        cu.set(true, "returnId", payment.getPaymentId());
        cu.set(true, "renkuanDate", DateUtils.getYear() + "-" + DateUtils.getMonth());
        cu.set(true, "customReturnState", CommonConstants.INT_2);
        cu.eq(true, "orderDetailsId", payment.getOrderDetailsId());
        return update(cu);
    }

    @Override
    public Boolean updateHuikuanInfo(BusOrderDetails orderDetails, BusOrder order) {
        CriteriaUpdate cu = new CriteriaUpdate();
        cu.set(true, "returnAmount", orderDetails.getSaleAmount());
        cu.set(true, "returnDate", DateUtils.formatDate(order.getTakeDate(), "yyyy-MM-dd"));
        cu.set(true, "renkuanDate", DateUtils.formatDate(order.getTakeDate(), "yyyy-MM"));
        if (FlymeUtils.isNotEmpty(orderDetails.getReturnId())) {
            cu.set(true, "returnId", orderDetails.getReturnId());
        }
        cu.set(true, "customReturnState", CommonConstants.INT_2);
        cu.eq(true, "orderDetailsId", orderDetails.getOrderDetailsId());
        return update(cu);
    }


    /**
     * 添加票折明细
     */
    public ResultBody addDiscountDetails(Long orderDetailsId, BigDecimal saleAmount) {
        BusOrderDetails busOrderDetails = orderDetailsService.getById(orderDetailsId);
        BigDecimal saleNum = busOrderDetails.getSaleNum();
        BigDecimal oldSaleAmount = busOrderDetails.getSaleAmount().subtract(saleAmount);
        //票折单价=(销售金额-票折金额)/数量
        //BigDecimal salePrice = oldSaleAmount.divide(saleNum, 3, BigDecimal.ROUND_HALF_UP);
        BusOrderDetails discountDetails = new BusOrderDetails();
        BeanUtils.copyProperties(busOrderDetails, discountDetails);
        //discountDetails.setSalePrice(salePrice);
        BigDecimal discountDetailsSaleNum = saleAmount.divide(busOrderDetails.getSalePrice(), 2, BigDecimal.ROUND_HALF_UP);
        discountDetails.setSaleNum(discountDetailsSaleNum.multiply(new BigDecimal("-1")));
        discountDetails.setOrderDetailsState(CommonConstants.INT_1);
        calculateSaleAmountByPiaozhe(discountDetails, saleAmount);
        discountDetails.setOrderDetailsId(IdWorker.getId());
        discountDetails.setReturnAmount(discountDetails.getSaleAmount());
        discountDetails.setSaleType(SaleTypeEnum.Pz.getCode().toString());
        discountDetails.setParentId(orderDetailsId);
        discountDetails.setCostAmount(new BigDecimal("0"));
        discountDetails.setCustomBond(new BigDecimal("0"));
        discountDetails.setSupplierBond(new BigDecimal("0"));
        discountDetails.setSalePrice(new BigDecimal("0"));
        discountDetails.setSaleNum(new BigDecimal("0"));
        discountDetails.setSettleSendAmount(new BigDecimal("0"));
        discountDetails.setCreateTime(DateUtils.getNowDateTime());
        discountDetails.setUpdateTime(DateUtils.getNowDateTime());
        discountDetails.setSettleFormulaContent("销售金额*(1-销售结算费率);");
        discountDetails.setSettleFormulaId(1694356126153920514L);
        discountDetails.setRefundFormulaId(1694356998535598081L);
        discountDetails.setRefundFormulaContent("销售金额*(1-供货方结算费率);");
        discountDetails.setHighTaxRateFormulaId(1336214847405187073L);
        discountDetails.setHighTaxRateFormulaContent("销售金额*供货方结算费率;");
        save(discountDetails);
        return ResultBody.msg("操作成功");
    }

    /**
     * 计算相关金额和价格
     *
     * @param piaozheAmount
     * @param orderDetails
     */
    private void calculateSaleAmountByPiaozhe(BusOrderDetails orderDetails, BigDecimal piaozheAmount) {
        Long orderId = orderDetails.getOrderId();
        Long orderDetailsId = orderDetails.getOrderDetailsId();
        BusOrderDetails old = getById(orderDetailsId);
        String saleType = old.getSaleType().toString();
        ApiAssert.isNotEmpty("订单ID不能为空", orderId);
        Long drugsId = orderDetails.getDrugsId();
        ApiAssert.isNotEmpty("药品ID不能为空", drugsId);
        BusOrder busOrder = orderService.getById(orderId);
        ApiAssert.isNotEmpty("订单不存在", busOrder);
        Long deptId = busOrder.getDeptId();
        Long customId = busOrder.getCustomId();
        BusCustom custom = customService.getById(customId);
        ApiAssert.isNotEmpty("客户不存在", custom);
        orderDetails.setCompanyId(busOrder.getCompanyId());
        orderDetails.setOrganizationId(busOrder.getOrganizationId());
        orderDetails.setDeptId(deptId);
        orderDetails.setSaleManId(busOrder.getSaleManId());
        orderDetails.setSaleDate(busOrder.getSendDate());
        orderDetails.setSupplierId(busOrder.getSupplierId());
        orderDetails.setCustomId(customId);
        Integer delivery = busOrder.getDelivery();
        //供货商资信方式
        Integer supplierBondType = busOrder.getSupplierBondType();

        //检查资信额度
        if (DeliveryTypeEnum.ZX.getCode().equals(delivery) && SaleTypeEnum.Xs.getCode().equals(saleType)) {
            BusDept busDept = deptService.getById(deptId);
            BigDecimal saleAmount = orderDetails.getSalePrice().multiply(orderDetails.getSaleNum());
            //资信额度
            BigDecimal reputationAmount = busDept.getReputationAmount();
            ApiAssert.gtzero("资信额度未配置", reputationAmount);
            BigDecimal userReputationAmount = FlymeUtils.getBigDecimal(totalReputationAmount(deptId), "0");
            //总额度-已用额度-当前添加商品销售额
            BigDecimal noUserAmount = reputationAmount.subtract(userReputationAmount).subtract(saleAmount);
            ApiAssert.gezero("资信额度不足", noUserAmount);
        }
        BusDrugs drugs = drugsService.getById(orderDetails.getDrugsId());

        OrderDetailsVo orderDetailsVo = new OrderDetailsVo();


        //查询供货方费率配置
        BusSupplierRate supplierRate = supplierRateService.findOrderSupplierRate(orderDetails, busOrder);
        //查询购货方费率配置
        BusCustomRate customRate = customRateService.findCustomRate(orderDetails, busOrder);

        orderDetailsVo.setCustomRate(customRate);
        orderDetailsVo.setSupplierRate(supplierRate);
        orderDetails.setCustomRateId(customRate.getCustomRateId());
        orderDetails.setSupplierRateId(supplierRate.getSupplierRateId());
        orderDetailsVo.setBusOrder(busOrder);
        BigDecimal saleNum = orderDetails.getSaleNum();
        BigDecimal salePrice = orderDetails.getSalePrice();
        EntityMap config = redisUtils.getConfigMap("DBR_CONFIG");
        orderDetails.setSaleAmount(piaozheAmount.multiply(new BigDecimal("-1")));
        if (FlymeUtils.isEmpty(orderDetails.getSupplierTaxRate())) {
            //供货方垫付款费率
            orderDetails.setSupplierTaxRate(supplierRate.getSupplierTaxRate());
        }
        if (FlymeUtils.isEmpty(orderDetails.getSupplierSettleRate())) {
            //供货方结算费率
            orderDetails.setSupplierSettleRate(supplierRate.getSupplierSettleRate());
        }
        if (FlymeUtils.isEmpty(orderDetails.getHighTaxRateFormulaId())) {
            //供货方高开税金公式
            orderDetails.setHighTaxRateFormulaId(supplierRate.getHighTaxRateFormulaId());
        }
        if (FlymeUtils.isEmpty(orderDetails.getRefundFormulaId())) {
            //供货方返款公式
            orderDetails.setRefundFormulaId(supplierRate.getRefundFormulaId());
        }


        if (FlymeUtils.isEmpty(orderDetails.getCustomSettleGapUpTaxRate())) {
            //结算高开税金费率
            orderDetails.setCustomSettleGapUpTaxRate(customRate.getCustomSettleGapUpTaxRate());
        }
        if (FlymeUtils.isEmpty(orderDetails.getCustomSettleRate())) {
            //结算费率
            orderDetails.setCustomSettleRate(customRate.getCustomSettleRate());
        }
        if (FlymeUtils.isEmpty(orderDetails.getCustomTaxRate())) {
            //结算保证金费率
            orderDetails.setCustomTaxRate(customRate.getCustomTaxRate());
        }
        if (FlymeUtils.isEmpty(orderDetails.getSettleFormulaId())) {
            //结算公式
            orderDetails.setSettleFormulaId(customRate.getSettleFormulaId());
        }
        Long supplierId = drugs.getSupplierId();
        //查询部门结算价(无配置取药品的结算价配置)
        BusCustomRate deptCustomRate = customRateService.findByDeptId(supplierId, drugsId, deptId);
        BigDecimal settlePrice = new BigDecimal("0");
        if (FlymeUtils.isNotEmpty(orderDetails.getSettlePrice()) && FlymeUtils.gtzero(orderDetails.getSettlePrice())) {
            //取录入的结算价
            settlePrice = orderDetails.getSettlePrice();
        }
        if (FlymeUtils.isNotEmpty(deptCustomRate)) {
            if (FlymeUtils.isEmpty(settlePrice) || FlymeUtils.lezero(settlePrice)) {
                settlePrice = FlymeUtils.getBigDecimal(deptCustomRate.getSettlePrice(), "0");
            }
            //设置结算价格
            orderDetails.setSettlePrice(settlePrice);
        }
        orderDetailsVo.setBusOrderDetails(orderDetails);
        orderDetails.setSettleSendAmount(new BigDecimal("0"));
        //成本价
        orderDetails.setCostPrice(new BigDecimal("0"));
        //成本金额
        orderDetails.setCostAmount(new BigDecimal("0"));
        //供货方高开金额(高开价格*数量)
        orderDetails.setSupplierGapUpAmount(new BigDecimal("0"));
        //计算供货方高开税金(垫付款税金)
        BigDecimal supplierGapUpTaxesAmount = calculateSupplierGapUpTaxes(orderDetailsVo);
        orderDetails.setSupplierGapUpTaxesAmount(supplierGapUpTaxesAmount);
        //计算供货方应返金额
        BigDecimal supplierRetable = piaozheAmount.multiply(new BigDecimal("-1")).multiply(new BigDecimal("1").subtract(orderDetails.getSupplierSettleRate())).setScale(2, BigDecimal.ROUND_HALF_UP);
        orderDetails.setSupplierRetable(supplierRetable);
        //必须设置结算价后再计算购货方保证金
        if (FlymeUtils.gtzero(settlePrice)) {
            //购货方底价计算方式1：按结算价 2:按成本价
            Integer floorPriceType = FlymeUtils.getInteger(drugs.getFloorPriceType(), 1);
            // 销售高开价格(销售-结算)
            BigDecimal customGapUpPrice = salePrice.subtract(settlePrice);
            //销售底价
            BigDecimal customFloorAmount = orderDetails.getSettleSendAmount();
            orderDetails.setCustomFloorAmount(customFloorAmount);
            //购货方高开金额
            BigDecimal customGapUpAmount = customGapUpPrice.multiply(saleNum);
            orderDetails.setCustomGapUpAmount(customGapUpAmount);
            // 销售结算高开税金费率
            BigDecimal customSettleGapUpTaxRate = FlymeUtils.getBigDecimal(orderDetails.getCustomSettleGapUpTaxRate(), customRate.getCustomSettleGapUpTaxRate());
            // 计算销售结算高开税金金额
            BigDecimal customSettleGapUpAmount = piaozheAmount.multiply(new BigDecimal("-1")).multiply(customSettleGapUpTaxRate);
            orderDetails.setCustomSettleGapUpAmount(customSettleGapUpAmount);

            // 计算销售保证金税金金额
            BigDecimal customGapUpTaxesAmount = calculateCustomGapUpRateAmount(orderDetailsVo);
            orderDetails.setCustomGapUpTaxesAmount(customGapUpTaxesAmount);

            //计算结算金额
            BigDecimal settleAmount = piaozheAmount.multiply(new BigDecimal("-1")).multiply(new BigDecimal("1").subtract(orderDetails.getCustomSettleRate())).setScale(2, BigDecimal.ROUND_HALF_UP);
            orderDetails.setSettleAmount(settleAmount);
            //公司利润
            BigDecimal profitAmount = calculateProfitAmount(orderDetailsVo);
            orderDetails.setProfitAmount(profitAmount);
        }
        //calculateCustomBond(orderDetails, busOrder, old.getRadio(), busOrder.getOverAmount());
    }

    @Override
    public List<EntityMap> selectByReturnDate(Long deptId, String financeMonth, String lastFirstDay) {
        CriteriaQuery cq = new CriteriaQuery(BusOrderDetails.class);
        cq.select(BusOrderDetails.class, "orderDetailsId", "saleDate", "saleNum", "salePrice", "saleAmount", "returnDate", "renkuanDate", "returnAmount");
        cq.addSelect(BusOrder.class, "orderId", "orderNo", "supplierBondType");
        cq.addSelect(BusDrugs.class, "drugsName", "drugsSpec");
        cq.addSelect(BusCustom.class, "customName", "areaName");
        //订单为上期
        cq.lt("bod.saleDate", lastFirstDay);
        //回款为本期
        cq.eq(true, "bod.renkuanDate", financeMonth);
        cq.ne(true, "bod.budan", financeMonth);
        cq.eq("bod.deptId", deptId);
        cq.eq("bod.orderDetailsState", CommonConstants.ENABLED);
        cq.createJoin(BusOrder.class);
        cq.createJoin(BusDrugs.class);
        cq.createJoin(BusCustom.class);
        return selectEntityMap(cq);
    }


    /**
     * 查询部门退上期保证金
     *
     * @param deptId
     * @param financeMonth
     * @param lastMonth
     * @return
     */
    @Override
    public List<EntityMap> selectTuiBenQi(Long deptId, String financeMonth, String lastMonth) {
        CriteriaQuery cq = new CriteriaQuery(BusOrderDetails.class);
        cq.select(BusOrderDetails.class, "orderDetailsId", "saleDate", "saleNum", "salePrice", "saleAmount", "renkuanDate", "customBondRetDate", "returnCustomBond");
        cq.addSelect(BusOrder.class, "orderId", "orderNo", "supplierBondType");
        cq.addSelect(BusDrugs.class, "drugsName", "drugsSpec");
        cq.addSelect(BusCustom.class, "customName", "areaName");
        //订单为上期
        cq.lt("bod.saleDate", lastMonth);
        //退款为本期
        cq.likeRight(true, "bod.customBondRetDate", financeMonth);
        cq.eq("bod.deptId", deptId);
        cq.ne(true, "bod.budan", financeMonth);
        cq.eq("bod.orderDetailsState", CommonConstants.ENABLED);
        cq.createJoin(BusOrder.class);
        cq.createJoin(BusDrugs.class);
        cq.createJoin(BusCustom.class);
        return selectEntityMap(cq);
    }


    /**
     * 查询部门本期调整上期保证金
     *
     * @param deptId
     * @param financeMonth
     * @param lastMonth
     * @return
     */
    @Override
    public List<EntityMap> selectBzjBenQi(Long deptId, String financeMonth, String lastMonth) {
        CriteriaQuery cq = new CriteriaQuery(BusOrderDetails.class);
        cq.select(BusOrderDetails.class, "orderDetailsId", "saleDate", "saleNum", "salePrice", "saleAmount", "customBond");
        cq.addSelect(BusOrder.class, "orderId", "orderNo", "supplierBondType", "takeDate");
        cq.addSelect(BusDrugs.class, "drugsName", "drugsSpec");
        cq.addSelect(BusCustom.class, "customName", "areaName");
        //订单为上期
        cq.lt("bod.saleDate", lastMonth);
        //收款为本期
        cq.likeRight(true, "ord.takeDate", financeMonth);
        cq.eq("bod.deptId", deptId);
        //只查询退货
        cq.eq("ord.orderType", 2);
        cq.eq("bod.orderDetailsState", CommonConstants.ENABLED);
        cq.createJoin(BusOrder.class);
        cq.createJoin(BusDrugs.class);
        cq.createJoin(BusCustom.class);
        return selectEntityMap(cq);
    }

    /**
     * 查询部门结算上期
     *
     * @param deptId
     * @param financeMonth
     * @param lastMonth
     * @return
     */
    @Override
    public List<EntityMap> selectJiesuanBenQi(Long deptId, String financeMonth, String lastMonth) {
        CriteriaQuery<BusOrderDetails> cq = new CriteriaQuery(BusOrderDetails.class);
        cq.select(BusOrderDetails.class, "orderDetailsId", "saleDate", "saleNum", "salePrice", "saleAmount", "renkuanDate", "settleAmount", "settleAmount2", "settlePayDate", "settlePayDate2", "settleRealAmount", "settleRealAmount2");
        cq.addSelect(BusOrder.class, "orderId", "orderNo", "supplierBondType");
        cq.addSelect(BusDrugs.class, "drugsName", "drugsSpec");
        cq.addSelect(BusCustom.class, "customName", "areaName");
        //订单为上期
        cq.lt("bod.saleDate", lastMonth);
        //结算为本期
        cq.likeRight(true, "bod.settlePayDate", financeMonth);
        cq.eq("bod.deptId", deptId);
        cq.ne(true, "bod.budan", financeMonth);
        cq.eq("bod.orderDetailsState", CommonConstants.ENABLED);
        cq.createJoin(BusOrder.class);
        cq.createJoin(BusDrugs.class);
        cq.createJoin(BusCustom.class);
        return selectEntityMap(cq);
    }

    /**
     * 查询部门结算上期
     *
     * @param deptId
     * @param financeMonth
     * @param lastMonth
     * @return
     */
    @Override
    public List<EntityMap> selectJiesuanBenQi2(Long deptId, String financeMonth, String lastMonth) {
        CriteriaQuery<BusOrderDetails> cq = new CriteriaQuery(BusOrderDetails.class);
        cq.select(BusOrderDetails.class, "orderDetailsId", "saleDate", "saleNum", "salePrice", "saleAmount", "renkuanDate", "settlePayDate", "settleAmount", "settleAmount2", "settlePayDate2", "settleRealAmount", "settleRealAmount2");
        cq.addSelect(BusOrder.class, "orderId", "orderNo", "supplierBondType");
        cq.addSelect(BusDrugs.class, "drugsName", "drugsSpec");
        cq.addSelect(BusCustom.class, "customName", "areaName");
        //订单为上期
        cq.lt("bod.saleDate", lastMonth);
        //结算为本期
        cq.likeRight(true, "bod.settlePayDate2", financeMonth);
        cq.eq("bod.deptId", deptId);
        cq.ne(true, "bod.budan", financeMonth);
        cq.eq("bod.orderDetailsState", CommonConstants.ENABLED);
        cq.createJoin(BusOrder.class);
        cq.createJoin(BusDrugs.class);
        cq.createJoin(BusCustom.class);
        return selectEntityMap(cq);
    }


    /**
     * 查询厂家对账本期回上期回款
     *
     * @param supplierId
     * @param financeMonth
     * @param lastFirstDay
     * @return
     */
    @Override
    public List<EntityMap> selectBenQiHuiShagnQi(Long supplierId, String financeMonth, String lastFirstDay) {
        CriteriaQuery cq = new CriteriaQuery(BusOrderDetails.class);
        cq.select(BusOrderDetails.class, "orderDetailsId", "saleDate", "saleNum", "salePrice", "saleAmount", "returnDate", "renkuanDate", "returnAmount");
        cq.addSelect(BusOrder.class, "orderId", "orderNo", "supplierBondType");
        cq.addSelect(BusDrugs.class, "drugsName", "drugsSpec");
        cq.addSelect(BusCustom.class, "customName", "areaName");
        //订单为上期
        cq.lt("bod.saleDate", lastFirstDay);
        //回款为本期
        cq.eq("bod.renkuanDate", financeMonth);
        cq.eq("bod.supplierId", supplierId);
        cq.ne(true, "bod.budan", financeMonth);
        cq.eq("bod.orderDetailsState", CommonConstants.ENABLED);
        cq.createJoin(BusOrder.class);
        cq.createJoin(BusDrugs.class);
        cq.createJoin(BusCustom.class);
        return selectEntityMap(cq);
    }


    /**
     * 查询厂家对账本期回上期返款
     *
     * @param supplierId
     * @param financeMonth
     * @param lastMonth
     * @return
     */
    @Override
    public List<EntityMap> selectBenQiFanShagnQi(Long supplierId, String financeMonth, String lastMonth) {
        CriteriaQuery cq = new CriteriaQuery(BusOrderDetails.class);
        cq.select(BusOrderDetails.class, "orderDetailsId", "saleDate", "saleNum", "salePrice", "renkuanDate", "saleAmount", "supplierRetDate", "supplierRealAmount");
        cq.addSelect(BusOrder.class, "orderId", "orderNo", "supplierBondType");
        cq.addSelect(BusDrugs.class, "drugsName", "drugsSpec");
        cq.addSelect(BusCustom.class, "customName", "areaName");
        //订单为上期
        cq.lt("bod.saleDate", lastMonth);
        //返款为本期
        cq.eq("bod.supplierRetDate2", financeMonth);
        cq.eq("bod.supplierId", supplierId);
        cq.ne(true, "bod.budan", financeMonth);
        cq.eq("bod.orderDetailsState", CommonConstants.ENABLED);
        cq.createJoin(BusOrder.class);
        cq.createJoin(BusDrugs.class);
        cq.createJoin(BusCustom.class);
        return selectEntityMap(cq);
    }

    /**
     * 查询厂家对账本期回上期垫付款
     *
     * @param supplierId
     * @param financeMonth
     * @param lastMonth
     * @return
     */
    @Override
    public List<EntityMap> selectBenQiDianShagnQi(Long supplierId, String financeMonth, String lastMonth) {
        CriteriaQuery cq = new CriteriaQuery(BusOrderDetails.class);
        cq.select(BusOrderDetails.class, "orderDetailsId", "saleDate", "saleNum", "salePrice", "renkuanDate", "saleAmount", "supplierBondPayDate", "supplierPayBond");
        cq.addSelect(BusOrder.class, "orderId", "orderNo", "supplierBondType");
        cq.addSelect(BusDrugs.class, "drugsName", "drugsSpec");
        cq.addSelect(BusCustom.class, "customName", "areaName");
        //订单为上期
        cq.lt("bod.saleDate", lastMonth);
        //垫付为本期
        cq.likeRight("bod.supplierBondPayDate", financeMonth);
        cq.eq("bod.supplierId", supplierId);
        cq.ne(true, "bod.budan", financeMonth);
        cq.eq("bod.orderDetailsState", CommonConstants.ENABLED);
        cq.createJoin(BusOrder.class);
        cq.createJoin(BusDrugs.class);
        cq.createJoin(BusCustom.class);
        return selectEntityMap(cq);
    }

    /**
     * 查询厂家对账本期回上期垫付款
     *
     * @param supplierId
     * @param financeMonth
     * @param lastMonth
     * @return
     */
    @Override
    public List<EntityMap> selectBenQiTuiDianShagnQi(Long supplierId, String financeMonth, String lastMonth) {
        CriteriaQuery cq = new CriteriaQuery(BusOrderDetails.class);
        cq.select(BusOrderDetails.class, "orderDetailsId", "saleDate", "saleNum", "salePrice", "saleAmount", "supplierRetBondDate", "returnSupplierBond");
        cq.addSelect(BusOrder.class, "orderId", "orderNo", "supplierBondType");
        cq.addSelect(BusDrugs.class, "drugsName", "drugsSpec");
        cq.addSelect(BusCustom.class, "customName", "areaName");
        //订单为上期
        cq.lt("bod.saleDate", lastMonth);
        //退垫付为本期
        cq.likeRight("bod.supplierRetBondDate", financeMonth);
        cq.eq("bod.supplierId", supplierId);
        cq.eq("bod.budan", 0);
        cq.eq("bod.orderDetailsState", CommonConstants.ENABLED);
        cq.createJoin(BusOrder.class);
        cq.createJoin(BusDrugs.class);
        cq.createJoin(BusCustom.class);
        return selectEntityMap(cq);
    }

    /**
     * 统计本年销售情况,按月分组
     *
     * @param params
     * @return
     */
    @Override
    public ResultBody totalSaleByType(Map params) {
        String type = params.getOrDefault("type", "year").toString();
        switch (type) {
            case "year":
                return totalSaleGroupYear(params);
            case "month":
                return totalSaleGroupMonth(params);
            case "week":
                return totalSaleGroupWeek(params);
        }

        return null;
    }

    /**
     * 统计本年销售情况,按月分组
     *
     * @param params
     * @return
     */
    private ResultBody totalSaleGroupYear(Map params) {
        Long companyId = OpenHelper.getCompanyId();
        String year = params.getOrDefault("year", DateUtils.getYear()).toString();
        CriteriaQuery cq = new CriteriaQuery(params, BusOrderDetails.class);
        cq.select("MONTH(saleDate) orderMonth", "count(DISTINCT orderId) orderCount", "sum(saleAmount) totalAmount");
        cq.eq("YEAR(saleDate)", year);
        cq.eq("orderDetailsState", CommonConstants.INT_1);
        Integer superAdmin = OpenHelper.getUser().getSuperAdmin();
        cq.eq(true, "companyId", OpenHelper.getCompanyId());
        cq.groupBy("orderMonth");
        cq.orderByAsc("saleDate");
        List<Map<String, Object>> list = listMaps(cq);
        //销售额
        List<Map<String, Object>> amountList = new ArrayList<>();
        //销售量
        List<Map<String, Object>> countList = new ArrayList<>();

        for (int i = 1; i <= 12; i++) {
            Map<String, Object> amountMap = new HashMap<>();
            Map<String, Object> countMap = new HashMap<>();
            amountMap.put("x", i + "月");
            countMap.put("x", i + "月");
            amountMap.put("y", 0);
            countMap.put("y", 0);
            for (Map<String, Object> map : list) {
                String totalAmount = map.get("totalAmount").toString();
                String orderCount = map.get("orderCount").toString();
                int month = FlymeUtils.getInteger(map.get("orderMonth").toString(), 0);
                if (month == i) {
                    amountMap.put("y", new BigDecimal(totalAmount));
                    countMap.put("y", Integer.parseInt(orderCount));
                }
            }
            amountList.add(amountMap);
            countList.add(countMap);
        }

        EntityMap result = new EntityMap();
        result.put("amountList", amountList);
        result.put("countList", countList);
        EntityMap saleMap = totalOrderByYear(params, "year");
        result.putAll(saleMap);
        return ResultBody.ok(result);
    }

    /**
     * 统计本月销售情况,按天分组
     *
     * @param params
     * @return
     */
    private ResultBody totalSaleGroupMonth(Map params) {
        EntityMap result = new EntityMap();
        String beign = DateUtils.getFirstDayOfMonth().toString();
        CriteriaQuery cq = new CriteriaQuery(params, BusOrderDetails.class);
        cq.select("DATE_FORMAT( saleDate, '%Y-%m-%d' ) AS time", "count(DISTINCT orderId) orderCount", "sum(saleAmount) totalAmount");
        cq.ge("saleDate", beign);
        cq.eq(true, "companyId", OpenHelper.getCompanyId());
        cq.le("saleDate", DateUtils.getLastDayOfMonth().toString());
        cq.groupBy("time");
        List<EntityMap> list = selectEntityMap(cq);
        //销售额
        List<Map<String, Object>> amountList = new ArrayList<>();
        //销售量
        List<Map<String, Object>> countList = new ArrayList<>();
        int num = DateUtils.getMonthDaysNum();
        for (int i = 0; i < num; i++) {
            String date = DateUtils.plusDays(DateUtils.getFirstDayOfMonth(), i);
            Map<String, Object> amountMap = new HashMap<>();
            Map<String, Object> countMap = new HashMap<>();
            amountMap.put("x", date);
            countMap.put("x", date);
            amountMap.put("y", 0);
            countMap.put("y", 0);
            for (Map<String, Object> map : list) {
                String totalAmount = map.get("totalAmount").toString();
                String orderCount = map.get("orderCount").toString();
                String d = map.get("time").toString();
                if (d.equals(date)) {
                    amountMap.put("y", new BigDecimal(totalAmount));
                    countMap.put("y", Integer.parseInt(orderCount));
                }
            }
            amountList.add(amountMap);
            countList.add(countMap);
        }
        result.put("amountList", amountList);
        result.put("countList", countList);
        EntityMap saleMap = totalOrderByYear(params, "month");
        result.putAll(saleMap);
        return ResultBody.ok(result);
    }

    /**
     * 统计本周销售情况,按天分组
     *
     * @param params
     * @return
     */
    private ResultBody totalSaleGroupWeek(Map params) {
        EntityMap result = new EntityMap();
        String beign = DateUtils.getFirstDayOfWeek().toString();
        CriteriaQuery cq = new CriteriaQuery(params, BusOrderDetails.class);
        cq.select("DATE_FORMAT( saleDate, '%Y-%m-%d' ) AS time", "count(DISTINCT orderId) orderCount", "sum(saleAmount) totalAmount");
        cq.ge("saleDate", beign);
        cq.eq(true, "companyId", OpenHelper.getCompanyId());
        cq.le("saleDate", DateUtils.getLastDayOfWeek().toString());
        cq.groupBy("time");
        List<EntityMap> list = selectEntityMap(cq);
        //销售额
        List<Map<String, Object>> amountList = new ArrayList<>();
        //销售量
        List<Map<String, Object>> countList = new ArrayList<>();

        for (int i = 0; i < 7; i++) {
            String date = DateUtils.getDayOfWeek(DateUtils.plusDays(DateUtils.getFirstDayOfWeek(), i));
            Map<String, Object> amountMap = new HashMap<>();
            Map<String, Object> countMap = new HashMap<>();
            amountMap.put("x", date);
            countMap.put("x", date);
            amountMap.put("y", 0);
            countMap.put("y", 0);
            for (Map<String, Object> map : list) {
                String totalAmount = map.get("totalAmount").toString();
                String orderCount = map.get("orderCount").toString();
                String d = map.get("time").toString();
                if (d.equals(date)) {
                    amountMap.put("y", new BigDecimal(totalAmount));
                    countMap.put("y", Integer.parseInt(orderCount));
                }
            }
            amountList.add(amountMap);
            countList.add(countMap);
        }
        result.put("amountList", amountList);
        result.put("countList", countList);
        EntityMap saleMap = totalOrderByYear(params, "week");
        result.putAll(saleMap);
        return ResultBody.ok(result);
    }

    /**
     * 统计订单销售排名,平台按店铺分组排名，店铺按商品分组排名,按月分组
     *
     * @param params
     * @return
     */
    private EntityMap totalOrderByYear(Map params, String type) {
        EntityMap result = new EntityMap();
        Long companyId = OpenHelper.getCompanyId();
        String year = params.getOrDefault("year", DateUtils.getYear()).toString();
        CriteriaQuery cq = new CriteriaQuery(params, BusOrderDetails.class);
        Integer superAdmin = OpenHelper.getUser().getSuperAdmin();
        cq.select("count(DISTINCT bod.orderId) saleCount", "sum(bod.saleAmount) saleAmount");
        cq.select(BusDept.class, "deptName name");
        cq.eq(true, "bod.companyId", companyId);
        cq.eq("orderDetailsState", CommonConstants.INT_1);
        cq.createJoin(BusDept.class);
        cq.groupBy("bod.deptId");
        cq.orderByDesc("saleAmount");

        switch (type) {
            case "year":
                cq.eq("YEAR(bod.saleDate)", year);
                break;
            case "month":
                cq.ge("bod.saleDate", DateUtils.getFirstDayOfMonth().toString());
                cq.le("bod.saleDate", DateUtils.getLastDayOfMonth().toString());
                break;
            case "week":
                cq.ge("bod.saleDate", DateUtils.getFirstDayOfWeek().toString());
                cq.le("bod.saleDate", DateUtils.getLastDayOfWeek().toString());
                break;
            case "day":
                cq.eq("to_days(bod.saleDate)", DateUtils.toDays());
                break;
        }


        List<EntityMap> list = orderDetailsService.selectEntityMap(cq);
        List<EntityMap> saleAmountList = new ArrayList<>();
        List<EntityMap> saleCountList = new ArrayList<>();
        if (FlymeUtils.isNotEmpty(list)) {
            for (EntityMap entityMap : list) {
                EntityMap amountMap = new EntityMap();
                EntityMap countMap = new EntityMap();
                BigDecimal amount = entityMap.getBigDecimal("saleAmount");
                Integer count = entityMap.getInt("saleCount");
                String name = entityMap.get("name");
                amountMap.put("name", name);
                amountMap.put("total", amount);
                countMap.put("name", name);
                countMap.put("total", count);
                saleAmountList.add(amountMap);
                saleCountList.add(countMap);
            }
            saleCountList = saleCountList.stream().sorted(Comparator.comparing(BusOrderDetailsServiceImpl::comparingByName).reversed()).collect(Collectors.toList());
        }
        result.put("saleAmountList", saleAmountList);
        result.put("saleCountList", saleCountList);
        return result;
    }

    @Override
    public List<EntityMap> getNoSettleList(Long orderDetailsId) {
        CriteriaQuery<BusOrderDetails> cq = new CriteriaQuery(BusOrderDetails.class);
        cq.eq("orderDetailsState", CommonConstants.INT_1);
        cq.nested(e -> e.eq("orderDetailsId", orderDetailsId).or().eq("parentId", orderDetailsId));
        List<EntityMap> list = selectEntityMap(cq);
        if (FlymeUtils.isNotEmpty(list)) {
            for (EntityMap entityMap : list) {
                Long drugsId = entityMap.getLong("drugsId");
                BusDrugs drugs = drugsService.getById(drugsId);
                if (FlymeUtils.isNotEmpty(drugs)) {
                    entityMap.put("drugsName", drugs.getDrugsName());
                    entityMap.put("drugsSpec", drugs.getDrugsSpec());
                }
                BigDecimal settleAmount = entityMap.getBigDecimal("settleAmount");
                BigDecimal settleAmount2 = entityMap.getBigDecimal("settleAmount2");
                BigDecimal settleAmount3 = entityMap.getBigDecimal("settleAmount3");
                BigDecimal settleRealAmount = entityMap.getBigDecimal("settleRealAmount");
                BigDecimal settleRealAmount2 = entityMap.getBigDecimal("settleRealAmount2");
                BigDecimal settleRealAmount3 = entityMap.getBigDecimal("settleRealAmount3");
                BigDecimal noSettleAmount = settleAmount.subtract(settleRealAmount);
                BigDecimal noSettleAmount2 = settleAmount2.subtract(settleRealAmount2);
                BigDecimal noSettleAmount3 = settleAmount3.subtract(settleRealAmount3);
                entityMap.put("noSettleAmount", noSettleAmount);
                entityMap.put("noSettleAmount2", noSettleAmount2);
                entityMap.put("noSettleAmount3", noSettleAmount3);
            }
        }
        return list;
    }

    private static Integer comparingByName(EntityMap map) {
        return map.getInt("total", 0);
    }

}
